5

一般的なリポジトリ パターンを実装しようとしています。よく説明されていると思うこのサイトを見つけました。 http://www.tugberkugurlu.com/archive/generic-repository-pattern-entity-framework-asp-net-mvc-and-unit-testing-triangle

私の目的は、開発者の時間とキーストロークを節約することであり、これが役立つことを知っています.

2 つの質問があります:
1. これは良いアプローチですか?
2. Unitofwork パターンとどのように組み合わせることができますか? もちろん、抽象クラスのインスタンスを作成することはできないため、次のコードは無効です。

public class UnitOfWork : IDisposable
    {
        #region Private fields
        private readonly MyCompanyContext _context = new MyCompanyContext();
        private GenericRepository<MyCompanyContext, Task> _taskRepository;

        public GenericRepository<MyCompanyContext, Task> TaskRepository
        {
            get
            {
                return _taskRepository ??
                         (_taskRepository = new GenericRepository<MyCompanyContext, Task>());
            }
        }




namespace MyCompany.DAL.Repository
{
    public interface IGenericRepository<T> where T : class
    {
        IQueryable<T> GetAll();
        IQueryable<T> FindBy(Expression<Func<T, bool>> predicate);
        void Add(T entity);
        void Delete(T entity);
        void Edit(T entity);
        void Save();
    }

    public abstract class GenericRepository<C, T> :
    IGenericRepository<T>
        where T : class
        where C : DbContext, new()
    {

        private C _entities = new C();
        public C Context
        {

            get { return _entities; }
            set { _entities = value; }
        }

        public virtual IQueryable<T> GetAll()
        {

            IQueryable<T> query = _entities.Set<T>();
            return query;
        }

        public IQueryable<T> FindBy(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
        {
            IQueryable<T> query = _entities.Set<T>().Where(predicate);
            return query;
        }

        public virtual void Add(T entity)
        {
            _entities.Set<T>().Add(entity);
        }

        public virtual void Delete(T entity)
        {
            _entities.Set<T>().Remove(entity);
        }

        public virtual void Edit(T entity)
        {
            _entities.Entry(entity).State = System.Data.EntityState.Modified;
        }

        public virtual void Save()
        {
            _entities.SaveChanges();
        }
    }
}
4

2 に答える 2

5

リポジトリに関してはいくつかの意見がありますが、私自身数年間本番環境でさまざまなリポジトリの実装を試した後、リポジトリ、特に汎用は冗長な抽象化レイヤーであるというAyende の意見に同意します。

私はこのコースがとても気に入りました: http://www.pluralsight-training.net/microsoft/Courses/TableOfContents/linq-architecture

考えられる解決策のほとんどを説明し、良い点と悪い点を説明しました。

私たちが現在使用しているのは、データ コンテキストに対する非常に薄い抽象化です。EF を使用する場合、ほとんどの場合、Linq2Sql のテスト容易性の問題を克服するためだけです。

于 2012-07-03T08:45:55.190 に答える
2

努力すればうまくいくかもしれませんが、本当にその努力に見合う価値があるのでしょうか? 以前にこのような実装を見たことがありますが、多対多の関係を管理しようとすると本当に苦労します (シナリオでそれをどのように管理するか考えてみてください)。ORMであるEntity Frameworkを使用していますか?Entity Framework や nHibernate などの ORM が設計されていますアプリケーション コードからデータベースの実装を抽象化するために、その上にさらに別の抽象化を追加してエンティティをそのような粒度レベルで管理する目的は何ですか? それがテストの問題である場合は、モック フレームワークを使用してコンテキストをモックすることができます。これにより、テスト中に実際のデータベースが不要になります。ただし、アーキテクチャまたはセキュリティ上の理由から、アプリ コードから db コンテキストとの対話を削除しようとしている場合は、エンティティ フレームワークの上にコマンド パターンの実装を使用する実用主義をお勧めします。セキュリティ上の理由から (正しいか間違っているかを問わず)、アプリケーション コードで db 接続を使用することは絶対に許可されていない大規模なエンタープライズ (銀行) アプリケーションでこれを行う必要がありました。

于 2012-07-03T08:46:37.093 に答える