2011-07-01 17 views
19

私は機能を有効/無効にするグローバルフラグを持っています。私はいくつかのフラグに依存していくつかの依存関係を注入したいと思います。いくつかの機能は、フラッグの値がfalseの場合はnullを、そうでない場合は実際の依存性を挿入するために、重く構築されたクラスを必要とします。 Ninjectはnullを注入できません。他のオプションはありますか?Ninject。オプションの注入

更新:コンストラクタ引数はOptionalAttribute属性で修飾することができます。この場合、対応するバインディングが見つからない場合、nullが挿入されます。ここに問題があります:ターゲットクラスが適切に構築できるかどうかは検証できません。私はそれがうまく構築することができるかどうかを確認する各公共の依存性のためのテストを持っています。フラグの値がtrueの場合、OptionalAttribute属性で装飾された依存関係を正しく構築できない場合、エラーを見つけることができません。私はバインディングレベルでしかそれを管理したいと思います。

答えて

17

ファクトリメソッド(つまりToMethod)を使用してバインドして注入動作を変更することができます。また、コンテナのAllowNullInjection設定を構成することでnullを注入することもできます。

もう1つの方法として、ファクトリメソッドを使用して、重量クラスではなく軽量のダミーオブジェクトを指定する方法があります。インターフェイスを使用している場合は、これは簡単ですが、何もしないインターフェイスの実装があるだけです。 FakeItEasyのような模擬フレームワークを使用して、これらのダミーを構築することさえできます。

public void Configure() 
{ 
    bool create = true; 

    IKernel kernel = new StandardKernel(); 

    kernel.Settings.AllowNullInjection = true; 

    kernel.Bind<IFoo>().ToMethod(ctx => create ? ctx.Kernel.Get<Foo>() : null); 

    DependendsOnIFoo depFoo = kernel.Get<DependendsOnIFoo>(); 
} 

private interface IFoo {} 

private class Foo : IFoo {} 

private class DependendsOnIFoo 
{ 
    public DependendsOnIFoo(IFoo foo) {} 
} 
:ここでの利点は、ダミークライアントが nullをチェックする必要はありません。つまり、クライアントには透過特別行動など

ファクトリメソッドを使用した例、プラスAllowNullInjectionとヌルを作ることです

で軽量なオブジェクトがフラグに応じて置換された例:

public void Configure() 
{ 
    bool heavy = true; 

    IKernel kernel = new StandardKernel(); 

    kernel.Bind<IFoo>() 
    .ToMethod(ctx => heavy ? ctx.Kernel.Get<HeavyFoo>() : (IFoo)new DummyFoo()); 

    DependendsOnIFoo depFoo = kernel.Get<DependendsOnIFoo>(); 
} 

private interface IFoo {} 

private class HeavyFoo : IFoo {} 

private class DummyFoo : IFoo { } 

private class DependendsOnIFoo 
{ 
    public DependendsOnIFoo(IFoo foo) {} 
} 
12

がnullの注入は、通常は賢明ではありません。この場合、より良い方法がある絶対に何もしないヌルオブジェクトを実装し、これを注入する

public interface IFoo 
{ 
    void Do(); 
} 

public class Foo : IFoo 
{ 
    public void Do() 
    { 
     DoSomething(); 
    } 
} 

public class UglyNullCheckingBar 
{ 
    IFoo foo; 
    public Bar(IFoo foo) 
    { 
     this.foo = foo; 
    } 

    public void Do() 
    { 
     if (this.foo != null) 
     { 
      this.foo.Do(); 
     } 
    } 
} 

の代わりに:これは、次のコードで示すように、オブジェクトがnullであるかどうかをチェックして、あなたのコードを汚染しますヌル。これにより、コードがきれいに保たれます。

public class NullFoo : IFoo 
{ 
    public void Do() {} 
} 

public class Bar 
{ 
    IFoo foo; 
    public Bar(IFoo foo) 
    { 
     this.foo = foo; 
    } 

    public void Do() 
    { 
     this.foo.Do(); 
    } 
} 
関連する問題