2016-04-27 6 views
2

私はこのようにlog4netのために与えるための型パラメータを持つLogManagerのクラスがあります。どのようにシングルトンクラスで過渡ロガーを使用するには、シンプルなインジェクター

public class LogManager<T> : ILogManager 
{ 
    private ILog Logger { get; set; } 

    public LogManager() 
    { 
     Logger = LogManager.GetLogger(typeof(T)); 
    } 
} 

を私は条件としてこのロガーを登録します。

container.RegisterConditional(typeof(ILogManager), 
c => typeof(LogManager<>).MakeGenericType(c.Consumer.ImplementationType), 
Lifestyle.Transient, 
c => true); 

それは私のコントローラのconstuctorsにログマネージャを注入し、それを使用するように動作します。しかし問題がある。私は、ログマネージャを使うべきシングルトンクラスもたくさん持っていますが、ログマネージャの寿命が短く、シンプルインジェクタではできません。

提案されている解決策は、ログファクトリクラスを他のシングルトンに注入し、悪い考えのように聞こえるたびに工場に電話をかけることです。私は何もしたくないときに_logFactory.GetLogger()。Debug( "log")を実行する必要があります。あるいは、この解決策について何か不足していますか?

他の提案された解決策は、意味を持たないシングルトンクラスを一時的にすることです。

私はどのように進めるべきですか?私のデザインに何か問題はありますか?あなたが登録シングルトンにする必要があります

+0

Sooo ...「LogManager 」をシングルトンとして登録してみませんか? – Steven

+0

これを行うと、ロギングを行うクラス情報が失われました。 – gmnnn

+0

これはテストしましたか? Log4netのLoggerクラスはスレッドセーフであり、各 'T'は独自の' LogManager 'インスタンスを取得します。 – Steven

答えて

3

LogManager<>ので

container.RegisterConditional(typeof(ILogManager), 
    c => typeof(LogManager<>).MakeGenericType(c.Consumer.ImplementationType), 
    Lifestyle.Singleton, 
    c => true); 

がジェネリック型で、シンプルなインジェクターは、閉じたジェネリックバージョンごとに1つのインスタンスを作成します。したがってLogManager<HomeController>LogManager<UsersController>とは異なるインスタンスです。これは単に同じインスタンスを使用する方法がないためです(これは.NETでは不可能です)。だから、各消費者はまだそれ自身のLogManager<T>を持っており、それ自身のlog4net ILogの実装である。 log4netのLogManager.GetLoggerから返されたロガーはスレッドセーフであり、それでなぜ自分のものを作るのに問題がないのですかLogManager<T>シングルトン。

+0

あなたは厳しいですが、私はこれについて少し混乱していました。 300以上の異なるロガーインスタンスを意味する300以上のコントローラーを持つことは問題ではないでしょうか? – gmnnn

+0

@gmmmメモリ消費の観点からは、問題はほとんどありませんが、ロガーを非常に多くのクラスに注入すると、保守性の問題が発生します。 [私の考えを得た答えだった] [この回答](https://stackoverflow.com/a/9915056/264697) – Steven

+0

私はクラスを簡素化しようとします。 – gmnnn

関連する問題