4

私は短期間 Ninject を使用しており、Unity で app.config/web.config エントリを使用して行ったことを行う方法を理解しようとしています。

私はこれが単純であると確信しています.それを実装するための最良の方法を見つけていないだけです.もちろん、Ninjectには最高のドキュメントがありません.

コードを変更せずに、インターフェイスのさまざまな実装が必要です。特定のアプリケーションは、使用する実装を認識しています。

たとえば、Unity を使用していたときは、ライブ アプリと単体テスト ライブラリがあり、異なるデータ ライブラリを使用していました。そう:

var repo = IoC.Get<IRepository>();

RealRepositoryライブアプリではa を返し、FakeRepository単体テストでは a を返します。app.config または web.config でクラスをマップするだけです。

Ninjectでは、コードでマッピングを定義するため、コードを除いて、使用する実装(またはモジュール)を決定する方法はないようです-しかし、もちろん全体の目的は私がしたくない使用したい実装を具体的に述べる必要があります。

これを行う良い方法はありますか?私が考えることができる唯一の方法は、構成ファイルから NinjectModule 実装を動的に選択することですが、それは正しくありません。

4

2 に答える 2

8

IoC コンテナーを Service Locator として誤用しているようです。これにより、多くの問題が発生します。その1つは、テストがはるかに難しいことです。代わりに正しく実行し、サービスの場所の代わりにコンストラクターの挿入を行うことをお勧めします。

これは、代わりに

public class MyClass
{
    public void Do()
    {
        var repo = IoC.Get<IRepository>();
        ....
    }
}

あなたがやる

public class MyClass
{
    private IRepository repo;
    public MyClass(IRepository repo)
    {
        this.repo = repo;
    }

    public void Do()
    {
        ....
    }
}

アプリケーションのルートの Get は 1 つだけです。それ以外はすべてコンストラクターを介して渡されます。

これにより、テストが非常に簡単になります。

var testee = new MyClass(new Mock<IRepository>());
于 2012-06-11T23:59:20.603 に答える
2

ライブ アプリと単体テスト ライブラリのエンドポイントが異なっていませんか? 1 つはおそらく単体テスト プロジェクト (nunit?) で、もう 1 つはアプリケーション (コンソール、Windows、または asp.net) です。

アプリの各タイプは、通常は個別のモジュール (のコンストラクターに渡す) を定義することによって、バインディングを個別に定義する必要がありますStandardKernel。1 つのセットは実際のアプリのマッピングを提供し、別のセットは単体テストのマッピングを提供します。後者は必要な場合とそうでない場合があります。理想的には、テストしている特定のクラスの依存関係を簡単にモックして、Ninject をまったく使用せずに渡す必要があります。実際には、Ninject を引き続き使用する方が便利な言い訳をたくさん見つけました。その場合、別のモジュールを作成するか、テスト自体でその場でカーネルを再バインドします。

于 2012-06-11T22:41:35.910 に答える