次のリポジトリがある場合:
public IQueryable<User> Users()
{
var db = new SqlDataContext();
return db.Users;
}
クエリが実行されたときにのみ接続が開かれることを理解しています。
public class ServiceLayer
{
public IRepository repo;
public ServiceLayer(IRepository injectedRepo)
{
this.repo = injectedRepo;
}
public List<User> GetUsers()
{
return repo.Users().ToList(); // connection opened, query fired, connection closed. (or is it??)
}
}
この場合でも、リポジトリにIDisposableを実装させる必要がありますか?
Visual Studio Code Metricsは、確かにそうすべきだと考えています。
IQueryableを使用しているのは、サービスレイヤーへのクエリ(フィルター、ページングなど)を制御できるためです。したがって、IQueryableを使用しているという事実についてアーキテクチャ上の議論をしないでください。
ところで-SqlDataContextは、Entity FrameworkのObjectContextクラスを拡張するカスタムクラスです(POCOパーティを持つことができます)。
だから質問-私は本当にIDisposableを実装する必要がありますか?
もしそうなら、各メソッドが同じリポジトリインスタンスを共有するので、これがどのように可能かわかりません。
編集
Depedency Injection(StructureMap)を使用して、具体的なリポジトリをサービスレイヤーに注入しています。このパターンはアプリスタックをたどります-私はASP.NETMVCを使用しており、具体的なサービスがコントローラーに注入されます。
言い換えると:
- ユーザーがURLをリクエスト
- 新しいリポジトリインスタンスで作成された新しいServiceLayerインスタンスを受け取るコントローラーインスタンスが作成されます。
- コントローラはサービスでメソッドを呼び出します(すべての呼び出しは同じリポジトリインスタンスを使用します)
- リクエストが処理されると、コントローラーはなくなります。
ハイブリッドモードを使用してコントローラーに依存性を注入しています。これにより、StructureMapのドキュメントによると、インスタンスがHttpContext.Current.Itemsに格納されます。
だから、私はこれを行うことはできません:
using (var repo = new Repository())
{
return repo.Users().ToList();
}
これがDIの全体のポイントを打ち負かすので。