1

私は、ILogインターフェイスと2つの可能な実装:コンソールログとファイルログを持っています。私はどのように私は可能性が思ったんだけどウィンザーキャッスル複数のコンポーネントを特定のサービス

private ILog log; 

public TestController(ILog _log) 
{ 
    log = _log; 
} 

:私は次のコードを持っている私のTestControllerで

container.Register(
      Component.For<ILogFactory>().ImplementedBy<LogFactory>().Named("first").OnCreate(x => x.initialize(LogType.Console, null)).LifestyleSingleton(), 
      Component.For<ILogFactory>().ImplementedBy<LogFactory>().Named("second").OnCreate(x => x.initialize(LogType.File, null)).LifestyleSingleton(), 
      Component.For<ILog>().UsingFactoryMethod(kernel => kernel.Resolve<ILogFactory>("first").GetLog(LogType.Console)).Named("first_log").LifestyleSingleton(), 
      Component.For<ILog>().UsingFactoryMethod(kernel => kernel.Resolve<ILogFactory>("second").GetLog(LogType.File)).Named("second_log").LifestyleSingleton() 
     ); 

:私は、それゆえ私は、コントローラのインストーラで次のコードを持っているMVCアプリケーションでウィンザー城を使用していますfirstlogまたはsecond_logという名前のILogを注入することを決定してください。

+0

を多くの偽のクラス(モックやスタブ)に0を渡します。アプリケーションの一部であるDI構成をテストしないでください。通常、単体テストでDIコンテナは使用しません。したがって、 'TestController'がモックであると仮定すると、このシナリオでテスト対象のクラスは何ですか?特定のロガーまたは特定のログファクトリをテストする場合は、テストで 'new'キーワードを使用してそのインスタンスを作成する必要があります。 – NightOwl888

+0

これは単体テストではありません。コントローラーTestControllerという名前をつけただけですが、myControllerなど、必要なものを呼び出すことができます。私はちょうどこのコントローラで、私はその名前に基づいて注入したいログを扱うことができるだろうかと思っています –

+0

ロギングに関しては、ロギングコンポーネント( 'ILog')とコンフィグレーション実行時にログファイル、コンソール、データベースなどの場所とデバッグ、警告、エラーなどのレベルを判断するために使用されます。これにより、コードを再コンパイルせずにログ設定を変更することができます。 Log4netはこれの良い例です。 –

答えて

0

私のシナリオの解決策が見つかりました。 TestControllerは、定義された2 ILogsを必要とする:

public class TestController : Controller 
{ 
private ILog log1; 
private ILog log2; 

public TestController(ILog _log1, ILog _log2) 
{ 
log1 = _log1; 
log2 = _log2; 
identifier = _identifier; 
} 

追加する必要がある:

container.Register(
Component.For<MyController>().DependsOn(
ServiceOverride.ForKey("_log1").Eq("first_log"), 
ServiceOverride.ForKey("_log2").Eq("second_log")).LifestyleTransient() 
); 

実際のデフォルトのコンテンツ置換:ユニットテストは、通常、被試験1クラスを有する

container.Register(
Classes. 
FromThisAssembly(). 
BasedOn<IController>(). 
If(c => c.Name.EndsWith("Controller")). 
LifestyleTransient()); 
0

ご迷惑をおかけします。

サブ依存性リゾルバを使用できます。これにより、別のコンポーネントの依存関係に対して特定のコンポーネントを解決することができます。コードは、TestControllerのコンストラクタ内のパラメータの名前に基づいてILogを解決する(テストされていない)べきです。 TestController(ILog first)は、firstという名前のILogを解決します。

container.Kernel.Resolver.AddSubResolver(new SubDepResolver(container.Kernel)); 

幸運、 Marwijn:

class SubDepResolver : ISubDependencyResolver 
{ 
    private IKernel kernel; 
    SubDepResolver(IKernel kernel) 
    { 
    this.kernel = kernel; 
    } 

    public bool CanResolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, 
    DependencyModel dependency) 
    { 
    if (model.GetComponentType() != typeof(TestController)) return false; 
    if (dependency.GetComponentType() != typeof(ILog)) return false; 
    return true; 
    } 

    public object Resolve(
    CreationContext context, 
    ISubDependencyResolver contextHandlerResolver, 
    ComponentModel model, 
    DependencyModel dependency) 
    { 
    var handlers = kernel.GetHandlers(typeof(ILog)); 
    var handler = handlers.Single(h => h.GetComponentName() == dependency.DependencyKey); 
    return handler.Resolve(context); 
    } 
} 

は、使用してリゾルバを追加します。

関連する問題