25

現在、次のコードを使用しています。

public class MyProvider
{
    public MyProvider()
    {
    }

    public void Fetch()
    {
        using (PopClient popClient = new PopClient())
        {
            ....
        }
    }
}

Fetch メソッドを単体テストできるようにする必要があり、PopClient をモックできないという事実のために、PopClient を呼び出すインターフェイスとラッパー クラスを作成しました。私の更新されたコードは次のようになります。

public class MyProvider
{
    private readonly IPopClient popClient;

    public MyProvider(IPopClient popClient)
    {
        this.popClient = popClient;
    }

    public void Fetch()
    {
        using (var pop3 = popClient)
        {
            ....
        }
    }
}

私は依存性注入に Ninject を使用していますが、Ninject はすでに PopClient のインスタンスを作成してコンストラクターに注入しているため、更新されたコードで using ステートメントがどのような影響を与えるかはよくわかりません。

using ステートメントは pop3 オブジェクトを破棄し、popClient オブジェクトをそのままにして、Ninject がそれを処理できるようにしますか、それとも using ステートメントが Ninject に干渉しますか?

この場合の適切なアプローチは何ですか?どんな洞察も非常に役に立ちます。

4

3 に答える 3

18

変数には、オブジェクトpop3への同じ参照が与えられるため、ステートメントが終了すると、ローカル変数とインスタンス変数の両方によって参照されるオブジェクトが Dispose()d になり、おそらく後で使用するために矛盾した状態になります。IPopClientpopClientusing

IPopClientの複数のインスタンスを呼び出しごとに 1 つずつ使用する場合はFetch()、「ファクトリ メソッド」を挿入する必要があります。

public class MyProvider
{
    private readonly Func<IPopClient> createPopClient;

    public MyProvider(Func<IPopClient> popClientFactory)
    {
        this.createPopClient = popClientFactory;
    }

    public void Fetch()
    {
        using (var pop3 = createPopClient())
        {
            ....
        }
    }
}

これで、 を呼び出すとFetch()、 への新しい参照を返すファクトリ メソッドが実行IPopClientされます。これは、そのメソッドへの他の呼び出しに影響を与えずに使用および破棄できます。

AutoFac は、追加のセットアップなしで、登録された型のファクトリ メソッドの注入をサポートします (そのため、名前になっていると思います)。Ninject コンテナーを構成するときは、特定の戻り値の型のファクトリ メソッドとして "getter" を明示的に登録する必要があると思います (ラムダのように単純にすることも()=>new PopClient()、コンテナーの解決メソッドの呼び出しを使用することもできます)。

于 2012-09-10T22:31:26.790 に答える
1

バインディングを設定するときは、スコープを宣言します。

https://github.com/ninject/ninject/wiki/Object-Scopes

Ninjectは、作成したオブジェクトに対してdisposeを呼び出すため、Ninjectに処理するオブジェクトにdisposeメソッドを記述してください。

于 2012-09-10T22:26:04.407 に答える