1

さまざまなプロジェクトで私が見つけた非常に一般的なロギングの目標は、ログエントリを作成するクラス/オブジェクトが独自のクラス/オブジェクト名をそのエントリに記録することです。ログエントリが例外およびスタックトレース用である場合、その情報は無料で含まれます。ただし、ログエントリが例外でない場合は、通常、他のさまざまなアプローチを使用してこの結果を取得します。

  1. クラスの名前(またはロガー自体!)を保持するconstフィールドを各クラスにハードコーディングします。ロギング時にロガーにその定数が与えられます。
  2. ロガーは、呼び出しスタックを反映するコードでラップされ、どのクラスがロギング呼び出しを行ったかを判別します。次に、名前がログエントリに追加されます。
  3. 各クラスには、注入されたクラスの名前をすでに知っているロガーインスタンスが注入されます。

#3の簡単な例は次のようになります。

ILogger logger = new MyLogger("AmazingClass");
IAmazingClass foo = new AmazingClass(logger);

私が知りたいのは、IOCコンテナ、特にUnityが、この「シナリオ#3」をエレガントに解決するのに役立つかどうかです。はいの場合、どのように?

答えは単純なはずだと思います。IOCコンテナは、構築および注入しようとしているクラスを「認識」し、タイプの解決が完了する前に「依存」情報を「依存者」に提供します。

たとえば、Unityはデリゲート登録と次のような「リバースリフレクション」登録を通じてこれを達成できる可能性があります。

var container = new UnityContainer();
container.RegisterType<ILogger, MyLogger>(new InjectionFactory(
    (Type targetOfInjection) => new MyLogger(targetOfInjection.Name)
);

私はその構文を作りましたが、それは完全に信じられます。そうは言っても、Unity(または別のIOCコンテナー)が提案された機能に対して実際に何を提供するのでしょうか?

ps私は個人的にロガーとロギングに「大丈夫」であり、例外以外のエントリのクラス/オブジェクト名をキャプチャしようとはしていません。コードをシンプルに保ちます。しかし、このアプローチを強制される場合は、通常、スタックリフレクションオプションを使用します(シナリオ#2)。例外以外のロギングステートメントでクラス名をキャプチャする必要がある場合に、人々が好む他のアプローチを知ることは興味深いでしょう。ただし、最終的には、この質問はIOCコンテナの使用に焦点を当てています。

4

1 に答える 1

1

とはいえ、Unity (または別の IOC コンテナー) は提案された機能に対して実際に何を提供するのでしょうか?

Unity の質問にはお答えできませんが、Simple Injectorを使用すると、次のように登録できます。

container.RegisterWithContext<ILogger>(context =>
    new MyLogger(context.ImplementationType.Name));

Simple Injector ドキュメントのAdvanced Scenarios セクションから、このコード スニペットRegisterWithContextを使用して拡張メソッドを追加する必要があります。大きな利点は、Simple Injector を使用すると、このコンテキスト ベースの登録でさえ非常に高速に解決されることです。

ただし、コンテキスト ベースのインジェクションは通常、設計上の匂いがすることに注意してください。フィールドのいたるところでこのパターンが見られるという事実は、それが正しいとは言えません。したがって、続行する前に、ログを取りすぎていないことと、アプリケーションの設計が SOLID の原則に従っていることを確認してください。

于 2013-03-18T18:26:16.943 に答える