私がよく読む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);
}
}
}
これは理にかなっていますか、それとも私は完全に間違った方向に進んでいますか?