2

リポジトリとUOWのパターンを読んでいますが、UOWは大量のデータを取得し、メモリ内のそのデータに変更を加えてから、特定の時点で変更をコミットしているようです。必要がなければ別のレイヤーを実装したくないので、UOWの責任をリポジトリに委任しようとしています(つまり、保存します)。

現在のアプリケーションのリポジトリは、次のようにすぐに保存を実行します。

public void DeleteBox(int BoxId)
        {
            var Box = GetBox(BoxId);
            if (Box != null)
            {
                foreach (var subBox in Box.Boxes.ToList())
                {
                    DeleteBox(subBox.BoxId);
                }

                if (Box.ParentBox != null)
                {
                    Box.ParentBox.Boxs.Remove(Box);
                    _db.SaveChanges();
                }
                _db.Boxs.Remove(Box);
                _db.SaveChanges();
            }
            else throw new InvalidOperationException("Cannot delete Box because it doesn't exist");
        }

コードは現在「機能」していますが、ここでSaveChangesを実行するのは理想的ではないのではないかと思います。WebAPIの構築を開始するときに、代わりにコントローラーアクションからsaveChangesを呼び出して、リポジトリ内のアプリケーションの状態を変更することを検討する必要がありますか?貯蓄がどのように行われるべきかをよりよく理解するのに役立つ記事や参考文献は素晴らしいでしょう-私は現時点で少し圧倒されています。

4

1 に答える 1

2

個人的には、ドメイン モデル オブジェクトのすべての CRUD 操作を処理し、インターフェイスを介してこのリポジトリを MVC コントローラーに渡す完全なリポジトリ クラスを作成するのが好きです。次に、コントローラーは、アプリケーション ロジックに応じて、リポジトリでさまざまなメソッドを実行します。

このアプローチには、主に次の 2 つの利点があると思います。

  1. リポジトリ内のデータ アクセス コードとコントローラー内のアプリケーション ロジック コードを明確に分離できます。したがって、リポジトリはデータ アクセスの完全な責任を負い、コントローラーはアプリケーション ロジックを維持します。
  2. これは、テスト用に構造化する効果的な方法です。インターフェイスを介してリポジトリをコントローラに渡すことで、RhinoMocks や Moq などのモック フレームワークを介してコントローラを完全にテストすることができます。効果的にテストすることが困難または不可能なデータ アクセス コードが、テストできない単一のクラスに集中しています。

たとえば、Product クラスで完全な CRUD 操作を行うコントローラーが必要だとします。以下に示すように、リポジトリ インターフェイスと実装を作成します。リポジトリの実装には、オブジェクト リレーショナル マッパー (ORM) またはデータ アクセス レイヤーのインスタンスが必要であることに注意してください。この例では、コンストラクターの ISession インターフェイスを介して nHibernate Session オブジェクトのインスタンスを渡します。

public interface IProductRepo
{
    List<Product> GetProducts();
    Product GetProduct(int Id);
    void DeleteProduct(int Id);
    void CreateProduct(Product product);
    void UpdateProduct(Product product);
}

public class ProductRepo : IProductRepo
{
    public ProductRepo(ISession session)
    {
         _session = session;  
    }

    public Product GetProduct(int Id)
    {
         return _session<Product>().Get(Id);
    }

    //Implementation of other methods of IProductRepo

     ISession _session;
}

このレポは、コンストラクター注入 (私のお気に入り) またはプロパティ注入を介してコントローラーに渡すことができます。したがって、コントローラーは次のようになります。

public class ProductController : ApiController
{
    public ProductController(IProductRepo repo)
    {
        _repo = repo;
    }
    public List<Product> GetProducts()
    {
        //other code as needed
        return _repo.GetProducts();
    }
    public Product GetProduct(int id)
    {
        //other code as needed
        return _repo.GetProduct(id);
    }
    public void PostProduct(Product product)
    {
        _repo.CreateProduct(product);
        //other code as needed
    }
    public void PutProduct(Product product)
    {
        _repo.UpdateProduct(product);
        //other code as needed
    }
    public void DeleteProduct(int id)
    {
        _repo.DeleteProduct(id);
        //other code as needed
    }
}

Microsoft には、この Web API の基本的な例を説明する優れた記事があります。

編集:リポジトリパターン

マーティン・ファウラーの言葉で

リポジトリは、ドメイン レイヤーとデータ マッピング レイヤーの間を仲介し、メモリ内のドメイン オブジェクト コレクションのように機能します。

これは通常、nHibernate や Entity Framework などのオブジェクト リレーショナル マッパー (ORM) またはデータ アクセス レイヤーと組み合わせて使用​​されます。したがって、リポジトリは、実際に永続レイヤーへの書き込みと読み取りを行う ORM またはデータ アクセス クラスのインスタンスを取得します。リポジトリは、ORM/データ アクセス クラスに対するすべてのクエリと CRUD 操作をカプセル化するために使用されます。

于 2013-03-03T21:50:57.430 に答える