2010-12-06 11 views
0

これは私が逃してしまった非常に単純なものか、これ以上のことがあるかどうか疑問に思います。型定義コンストラクタを使用したセッター注入

基本的に、私がやっているのは、ロガーの実装にStructureMapのセッターインジェクションを使うことです。私はこれとして、それを初期化し、私のブートストラップコードで

public class Logger : ILogger 
{ 
    private ILog _log = null; 

    public Logger() { _log = LogManager.GetCurrentClassLogger(); } 

    public Logger(string name) { _log = LogManager.GetLogger(name); } 

    public Logger(Type loggerType) { _log = LogManager.GetLogger(loggerType); } 

    // The rest of the implementation... 
} 

ObjectFactory.Configure(x => { 
    x.FillAllPropertiesOfType<ILogger>().Use(l => 
     new Logger(l.BuildStack.Current.ConcreteType)); 
    // Further unrelated bootstrapping... 
}); 

それはかなり働いていないのStructureMapを使用するために、私は希望ロガーのコンストラクタは、ロガーを作成するためのTypeパラメータを受け入れます100%、それはおそらく私の部分の完全な理解の欠如です。だから私は、私が見ている行動に関するいくつかの質問があります。

  1. を「タイプ」私は、デバッガをステップとlog4netの実装にドリルダウンしたときにロガーが、見ていることを、​​です。どのように私はsetterが注入されている型のものになるようにすることができますか?
  2. StructureMapで構築されたインスタンスのセッターだけが設定されています。例えば、データアクセス層のためのリポジトリインタフェース/実装上。私のビジネスモデルなどの他のオブジェクトは、StructureMapグラフから作成されず、通常のようにインスタンス化されます。 StructureMapにもそれらを注入するよう指示する方法はありますか?私はそこにはないと思います。それはどういうことでしょうか?だから、どのようにタイプの適切に構築されたロガーのインスタンスを解決することができますか? (私はサービスロケータを介して行う決議者に電話する方法を知っていますが、この特定の必要性のために呼び出す方法ではありません)
  3. 「これはちょうどいい気分ではありません。名前付きインスタンスについて何か不足しているのでしょうか?ブートストラップがこの実装をグラフ化すると、setterを持つ各クラスに対して、どのように/いつインスタンスを提供するのでしょうか?

多分私がやろうとしていることを達成するために全く異なる/より簡単な方法があります。基本的には、IoCコンテナの背後にあるロギング実装を抽象化しています。クラス固有のロガーが必要です。

答えて

1

おそらくこれはあなたが探している正確な答えではありませんが、ILoggerFactoryを作成してすべてを単純化してみませんか?代わりに​​を登録するには、ILoggerFactoryを登録し、あなたのクラスでILoggerFactoryを注入することができます

public interface ILoggerFactory 
{ 
    ILogger CreateFor(string name); 
    ILogger CreateFor<T>(); 
    ILogger CreateFor(Type loggerType); 
} 

public class LoggerFactory : ILoggerFactory 
{ 
    public ILogger CreateFor(string name) 
    { 
     return LogManager.GetLogger(name); 
    } 

    public ILogger CreateFor<T>() 
    { 
     return CreateFor(typeof(T)); 
    } 

    public ILogger CreateFor(Type loggerType) 
    { 
     return LogManager.GetLogger(loggerType); 
    } 
} 
+1

興味深いです。それはちょうど行く方法かもしれません。正しいロガーを直接注入するほどエレガントではないようですが、それはうまくいくものです。正直言って、私は既存の実装が完全にエレガントであるとは思わなかった。クラスの内部ロガーについて公然と設定可能なことは、私と一緒に座っているだけではありません。 (注:これは私の実装ではなく、単にブートストラップしようとしています) – David

+1

私はこれをかなりエレガントなものにしましたが、コアの原則はあなたの提案と同じです。私のIoCブーストラッパーは、ILoggerFactoryとデフォルトのILoggerを結びつけます。前者はデフォルト以外のロガーを取得するために使用できます。提案していただきありがとうございます! – David

+2

Btw。タイプ固有のロガーインスタンスを本当に使用する必要がありますか?私はこれがlog4netの機能だと知っていますが、私はこれを必要としませんでした。私はしばしば、開発者が実際に例外を投げかけていたはずの場所に情報を記録していることをよく見ています。これらのいくつかのケースでは、ログに書き込む必要があります。これにより、メッセージには何が起こっているのかが明確に示されます(スタックトレースがない場合)。これを行うことができたら、ILoggerを再度注入してシングルトンとして登録することができます。人生をはるかに簡単にします。 – Steven

関連する問題