3

私がよく読むEntityFrameworkからコンテキストを読み書きするときは、コンテキストのライフサイクルをできるだけ短くすることをお勧めします(作業単位ごとに1つのコンテキスト)。それを行うことは非常に理にかなっていますが、すべてのメソッドでこのコンテキストを作成および破棄するクラスの単体テストをどのように作成する必要がありますか?

簡略化された架空のサンプルコードスニペットを見てみましょう。

public class Resource : IResource {
    public Item GetItem(string name) {
        using(var context = new DbContext()) {
            return context.Items.FirstOrDefault(item => item.Name == name);
        }
    }
}

リソースの単体テストを行う場合は、DbContextをモックしたいので、偽のデータが返されます。

私の通常のアプローチは、DbContextをクラスのプロパティにして、次のように外部から注入することです。

public class Resource : IResource {
    public DbContext Context { private get; set; }

    public Item GetItem(string name) {
        return this.Context.Items.FirstOrDefault(item => item.Name == name);
    }
}

このように、コンテキストを注入するインスタンス化クラスはライフサイクルに責任があり、使用を省略でき、もちろんモックされたコンテキストを注入できます。

ここで、長寿命のコンテキストを提供することは悪い考えである可能性があり、作業単位の原則ごとに1つのコンテキストに従うことを考慮すると、このオプションは好ましくありません。

では、どのようなオプションがありますか?1つのアイデアは、次のようにオンデマンドでコンテキストを作成および破棄するContextFactoryを注入することです。

public class Resource : IResource {
    public DbContextFactory ContextFactory { private get; set; }

    public Item GetItem(string name) {
        using(var context = ContextFactory.CreateContext()) {
            return context.Items.FirstOrDefault(item => item.Name == name);
        }
    }
}

これは理にかなっていますか、それとも私は完全に間違った方向に進んでいますか?

4

2 に答える 2

2

オプションは、メソッドインジェクションを使用することです。

   public Item GetItem(string name, DbContext context) {
        using(var context) {
            return context.Items.FirstOrDefault(item => item.Id == id);
        }
    }

また、Seemannの著書「.Netの依存性注入」では、このメソッドを使用して、呼び出しごとに変化する可能性のある依存性を注入しています。

しかし、私は使用しますContextFactory

于 2013-03-08T16:49:33.393 に答える
1

私はマーク・シーマンの本(アントン・シジコフが言及)をチェックしましたが、彼は実際に工場も使用しており、それを一時的な使い捨てと呼んでいます。工場がDIコンテナの代わりに使い捨ての依存関係の存続期間を管理しているため、これはどういうわけかリークのある抽象化です。それでも、破棄された使い捨てや、破棄された共有依存関係によって引き起こされる例外が原因でメモリリークが発生するよりはましです。

于 2013-06-14T07:43:22.040 に答える