59

私は完全な初心者です

私は他の誰かのコードを分解していて、nInjectモジュールのいくつかのインスタンスを見つけました-Ninject.Modules.Moduleから派生したクラスであり、それらのコードのほとんどを含むloadメソッドがあります。

これらのクラスは、StandardKernelのインスタンスのLoadModuleメソッドを呼び出し、それにモジュールクラスのインスタンスを渡すことによって呼び出されます。

ここで明らかな何かが欠けているかもしれませんが、単純な古いクラスを作成してそのメソッドを呼び出すだけでなく、静的メソッドを使用して静的クラスを呼び出すよりも、これの利点は何ですか?

 

4

3 に答える 3

62

Ninjectモジュールは、さまざまなタイプをIoCコンテナーに登録するために使用されるツールです。利点は、これらのモジュールが独自のクラスに保持されることです。これにより、独自のモジュールにさまざまな層/サービスを配置できます。

// some method early in your app's life cycle
public Kernel BuildKernel()
{
    var modules = new INinjectModule[] 
    {
        new LinqToSqlDataContextModule(), // just my L2S binding
        new WebModule(),
        new EventRegistrationModule()
    };
    return new StandardKernel(modules);
}

// in LinqToSqlDataContextModule.cs
public class LinqToSqlDataContextModule : NinjectModule
{
    public override void Load()
    {
        Bind<IRepository>().To<LinqToSqlRepository>();
    }
}

複数のモジュールを使用すると、IoCコンテナ内であっても、関心の分離が可能になります。

残りの質問は、Ninjectだけでなく、IoCとDI全体に関するもののように聞こえます。はい、静的構成オブジェクトを使用して、IoCコンテナーが実行するほぼすべてのことを実行できます。依存関係の階層が複数ある場合、IoCコンテナーは非常に便利になります。

public interface IInterfaceA {}
public interface IInterfaceB {}
public interface IInterfaceC {}

public class ClassA : IInterfaceA {}

public class ClassB : IInterfaceB
{
    public ClassB(IInterfaceA a){}
}

public class ClassC : IInterfaceC
{
    public ClassC(IInterfaceB b){}
}

ClassCの構築は、インターフェースの深さが複数あるため、現時点では苦痛です。カーネルにIInterfaceCを要求する方がはるかに簡単です。

var newc = ApplicationScope.Kernel.Get<IInterfaceC>();
于 2010-01-13T12:18:30.683 に答える
9

ここで明らかな何かが欠けているかもしれませんが、単純な古いクラスを作成してそのメソッドを呼び出すだけでなく、静的メソッドを使用して静的クラスを呼び出すよりも、これの利点は何ですか?

Bind<X>().To<Z>()はい、モジュールなしで、一連のステートメントを呼び出してバインディングをセットアップできます。

違いは、これらのステートメントをモジュールに入れると、次のようになることです。

  • IKernel.Load(IEnumerable<Assembly>)リフレクションを通じてそのようなモジュールを動的に検出し、それらをロードできます。
  • バインディングは、名前の下で論理的にグループ化されます。この名前を使用して、それらを再度アンロードできます。IKernel.Unload(string)
于 2010-01-13T14:08:12.740 に答える
3

ここで明らかな何かが欠けているかもしれませんが、単純な古いクラスを作成してそのメソッドを呼び出すだけでなく、静的メソッドを使用して静的クラスを呼び出すよりも、これの利点は何ですか?

私たちにとって、それは後で非常に簡単にテストを追加する機能です。いくつかのバインディングをモックオブジェクトと出来上がりでオーバーライドするだけです.....「すべて」を配線したDIのないレガシーコードでは、手直しなしでテストケースの挿入を開始することはほぼ不可能です。DIを配置し、DIがすべてを配線する場所で適切に使用されている限り、非常に醜い可能性のあるレガシーコードでも簡単に実行できます。

多くのDIフレームワークでは、モックオブジェクトとの特定のバインディングをオーバーライドするテストモジュールを使用して、テスト用の本番モジュールを使用できます(残りの配線はそのままにしておきます)。これらは単体テストよりもシステムテストかもしれませんが、クラス間の統合をテストし、プロジェクトに参加して機能全体を実際に見ることができる人にとっては素晴らしいドキュメントであるため、平均的な開発者よりも高レベルのテストを好む傾向があります(代わりに機能の一部のみ)システム全体をセットアップする必要はありません)。

于 2011-12-28T14:08:30.123 に答える