2016-11-02 14 views
0

私はIoCコンテナとしてSimple Injectorを使用しています。私は実行スコープの存在に基づいて私のクラスのロガーに注入したいと思います。デフォルトのロガー(シングルトン)と私のコンテキストに基づくものがなければなりません。ライフスタイルsimpleinjectorに基づいて登録を実装

container.RegisterConditional(typeof(ILogger), 
    x => typeof(NContextLogger<>).MakeGenericType(x.Consumer.ImplementationType), 
    Lifestyle.Scoped, 
    x => container.GetCurrentExecutionContextScope() != null); 

container.RegisterConditional(typeof(ILogger), 
    x => typeof(NLogger<>).MakeGenericType(x.Consumer.ImplementationType), 
    Lifestyle.Singleton, 
    x => container.GetCurrentExecutionContextScope() == null); 

問題はNContextLogger<>の任意のインスタンスを作成すると次のとおりです。

は、私はすでにこのような何かを試してみました。シングルトンのNLogger<>を作成すると、simpleinjectorはNContextLoggerのインスタンスを作成しようとしていないためです。

+0

私は、このAを見つけると言わなければなりませんかなり奇妙な要件。アクティブな実行コンテキストスコープのコンテキスト外のオブジェクトを解決したいのはなぜですか?おかげさまで – Steven

答えて

2

RegisterConditionalに指定された述部は、述語の結果がキャッシュされ、式ツリーとコンパイルされたデリゲートに書き込まれるため、実行時の意思決定に使用できません。しかし、 GetCurrentExecutionContextScope() Lifestyle.Scoped.GetCurrentScope(Container)の可用性は実行時の決定です。

実行時条件に基づく決定は、(runtime data shouldn't be injected into componentsと同じ理由で)オブジェクトグラフの作成中には行わないでください。

オブジェクトグラフの作成中に実行時の条件に基づいて決定するのではなく、オブジェクトグラフを作成するまでこれらの決定を延期する必要があります。これを行うための最も明白な方法は、プロキシクラスを導入することである:

public sealed class ProxyLogger<T> : ILogger 
{ 
    private readonly Container container; 

    public ProxyLogger(Container container) { 
     this.container = container; 
    } 

    // Implement ILogger method(s) 
    public void Log(string message) => Logger.Log(message); 

    private ILogger Logger => Lifestyle.Scoped.GetCurrentScope(container) == null 
     ? container.GetInstance<NLogger<T>>() 
     : container.GetInstance<NContextLogger<T>>(); 
} 

をこのプロキシクラスを使用すると、次の登録が要件を満たすために作ることができます。

container.RegisterConditional(typeof(ILogger), 
    c => typeof(ProxyLogger<>).MakeGenericType(x.Consumer.ImplementationType), 
    Lifestyle.Singleton, 
    c => true); 

container.Register(typeof(NLogger<>), typeof(NLogger<>), Lifestyle.Singleton); 
container.Register(typeof(NContextLogger<>), typeof(NContextLogger<>),Lifestyle.Singleton); 
+0

ProxyLoggerは私が探していたものです。 – Raik

関連する問題