0

環境:ASP.NET MVC3 C#

リポジトリ(セミプセド)があるとしましょう:

public interface IRepository
{
 create();read();update();delete();opendb();closedb();
}

public class CarRepository : IRepository
{
 private DbContext namedDbContext;

 public void opendb()
 {
  namedDbContext = new DbContext();
 }
 public void closedb()
 {
  namedDbContext.dispose();
 }
}

次に、コントローラーにリポジトリーが挿入され、次のように使用されて、データベース接続の有効期間を手動で制御します。

public class SomeController : Controller
{
    private IRepository CarRepository;

    public void SomeController(IRepository _carRepository)
    {
        CarRepository = _carRepository;
    }

    public ActionResult SomeAction(int CarId)
    {
        CarRepository.opendb();
        var car = CarRepository.read(CarId);
        CarRepository.closedb();
    }
}

これは、リポジトリから接続を制御してコントローラーに配置するため、悪い習慣と見なされますか?依存性注入を使用することによるメモリリークが心配であり、重複する接続が開かれたり、長時間実行されて使用されたりしないようにしたいと考えています。

4

3 に答える 3

2

はい。もちろん。ほとんどのADO.NETドライバーは接続プールを使用するため、実際の接続プロセスはそれほど重くありません。またTransactionScope、複数の接続を介したトランザクションを処理できるものがありますが、1つの接続を介した1つのトランザクションほど高速ではありません。

依存性注入を使用することによるメモリリークが心配であり、重複する接続が開かれたり、長時間実行されて使用されたりしないようにしたいと考えています。

IoCは接続のクリーンアップを保証します(大規模なユーザーベースがそれを確認しています)。プログラマーがすべての場所でクリーンアップを行うという保証はありません。

于 2012-02-13T19:31:36.430 に答える
1

REpositoryパターンは、永続層の抽象化を提供します。db接続などの永続性の詳細を公開しないでください。ストレージがxmlファイルまたはクラウドストレージの場合はどうなりますか?

そうです、それは悪い習慣です。より詳細な制御が必要な場合は、リポジトリで作業単位パターンを使用するようにして、トランザクションがいつコミットされるかをより高いレベルで決定する必要がありますが、それだけです。データベースに関する知識は、リポジトリによって公開されるべきではありません。

メモリリークについては、リポジトリの実装IDIsposable(未処理の開いている接続を閉じる場所)を作成し、DIコンテナがリクエストごとにリポジトリインスタンスを管理していることを確認すると、Disposeが呼び出されます。

于 2012-02-13T19:47:22.293 に答える
1

リポジトリの一部は、永続性の詳細を抽象化しています。

あなたの提案には2つの問題があります。

  1. これらのメソッドに「opendb」と「closedb」という名前を付けて、必要以上に抽象化をリークしています。
  2. このルートをたどる場合はIDisposable、メソッドから(接続オブジェクト)を返しopendb()、アクションをブロックにラップしusingて、接続が確実に閉じられるようにする必要があります。

通常、リポジトリに各メソッドの接続を作成させることができるため、リポジトリメソッドで正しく接続する必要があります。課題は、ピースごとに個別の接続を使用せずに、リポジトリに対して複数のアクションを実行する場合に発生します。

これを実現するために、リポジトリから作業単位の概念を公開できます。作業単位はリポジトリのメソッドのインターフェースを実装するため、作業単位の外部でメソッドを呼び出すことはできません。また、を実装するIDisposableため、リポジトリを呼び出すときは常にusingブロックを使用します。内部的には、リポジトリが接続を管理しますが、接続を公開したり、「それについて話したり」することはありません。

例えば:

public ActionResult SomeAction(int CarId)
{
     using (var repo = CarRepository.BeginUnitOfWork())
     {
        var car = repo.read(CarId);
        // do something meaningful with the car, do more with the repo, etc.
     }
}
于 2012-02-13T19:44:31.420 に答える