2016-05-23 4 views
2

私は中小規模のプロジェクトを開始しようとしています。私は決してソフトウェアアーキテクトではない。しかし、私は時々行うすべての動きに疑問を抱く傾向があります。私は正しいことをしたいので。単純なリポジトリasp.net mvc with entity framework

私は単純なリポジトリを実装する方法を見つけました。これが "正しい"方法であるかどうかを知りたかったのです。私は知識がある前に何が起こっているのかを知っていて、複雑なものを取り入れていないので、私はこの解決策に来ました:)

ここでそれが行きます。私は同じdbcontextの下にすべての私のリポジトリを維持することを確認し、作業

ユニット。私の宇宙では、コントローラから呼び出すときにすべてのレポにアクセスすることができます。

public class UnitOfWork : IDisposable 
{ 
    private ContactRepository _contactRepo; 
    private ApplicationDbContext _entities; 

    public UnitOfWork(ApplicationDbContext entities) 
    { 
     _entities = entities; 
    } 

    public ContactRepository ContactRepo 
    { 
     get 
     { 
      if (_contactRepo == null) 
      { 
       _contactRepo = new ContactRepository(_entities); 
      } 
      return _contactRepo; 
     } 
    } 


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

    private bool disposed = false; 

    protected virtual void Dispose(bool disposing) 
    { 
     if (!this.disposed) 
     { 
      if (disposing) 
      { 
       _entities.Dispose(); 
      } 
     } 
     this.disposed = true; 
    } 

    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 
} 

ContactRepository

これは、それがdbcontextをrecievesと私が好きなデータをつかむためにそれを使用してリポジトリの短い例である

public class ContactRepository 
    { 
    private ApplicationDbContext _entities; 

    public ContactRepository(ApplicationDbContext entities) 
    { 
     _entities = entities; 
    } 

    public IEnumerable<Contact> GetAll() 
    { 
     return _entities.Contacts; 
    } 
} 

コントローラ

翔私は私が目指したのと同じdbcontext下のすべての私のリポジトリにアクセスする必要があります。このように、コントローラ

public class ContactController : Controller 
{ 

    UnitOfWork uow = new UnitOfWork(new ApplicationDbContext()); 

    public ActionResult Index() 
    { 
     var contacts = uow.ContactRepo.GetAll(); 
     return View(contacts); 
    } 



    protected override void Dispose(bool disposing) 
    { 
     uow.Dispose(); 
     base.Dispose(disposing); 
    } 
} 

のRT例。

私は物事がよりスマートに/異なることができることを知っています。たとえば、拡張可能な汎用リポジトリを使用します。しかし、この場合、私は単純で分かりやすいものを目指しています。しかし、大きな欠陥がある場合、まだ大きな勘違いをしたくない。

データトラフエンティティフレームワークをこのように処理する方法に大きな欠陥がありますか?

+0

アーキテクチャは罰金です私には、どちらも建築家ではありません。 http://codereview.stackexchange.com/ – Eldho

答えて

0

単純なものを目指しているのであれば、Entity Frameworkを使用してください。しかし、リポジトリパターンを使用する場合は、適切に行うことをお勧めします。リポジトリを使用するための最大の動機の

二つがあります:

  1. あなたのdatabase.ThisにCRUDアプリケーションを簡素化したい は、あなたがしたいインタフェースとジェネリック
  2. の使用を介して行われます外部dependencies.Againから分離 のビジネスロジックをテストする能力は、これは インターフェイス
の使用を介して行われ

以下は実装に2分かかりますが、効果的な方法で素晴らしいパターンを実装しようとしている瞬間から、少なくとも正しいことをしていることは分かっています。

ジェネリックインターフェイス:

public interface IRepository<T> 
    { 
     T GetById(int id); 
     IEnumerable<T> List(); 
     IEnumerable<T> List(Expression<Func<T, bool>> predicate); 
     void Add(T entity); 
     void Delete(T entity); 
     void Update(T entity); 
    } 

ジェネリックリポジトリ:仕事の

public abstract class EntityBase 
    { 
    } 

    public class DBRepository<T> : IRepository<T> where T : EntityBase 
    { 
     private readonly DbContext _dbContext; 

     public DBRepository(DbContext dbContext) 
     { 
      _dbContext = dbContext; 
     } 

     public virtual T GetById(int id) 
     { 
      return _dbContext.Set<T>().Find(id); 
     } 

     public virtual IEnumerable<T> List() 
     { 
      return _dbContext.Set<T>().AsEnumerable(); 
     } 

     public virtual IEnumerable<T> List(System.Linq.Expressions.Expression<Func<T, bool>> predicate) 
     { 
      return _dbContext.Set<T>() 
        .Where(predicate) 
        .AsEnumerable(); 
     } 

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

     public void Update(T entity) 
     { 
      _dbContext.Entry(entity).State = EntityState.Modified; 
     } 

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

は単位:

public class UnitOfWork : IDisposable 
{ 
    private bool disposed = false; 
    private ApplicationDbContext context = new ApplicationDbContext(); 

    private IRepository<Contact> _contactRepository; 

    public IRepository<Contact> ContactRepository 
    { 
     get 
     { 
      if (this._contactRepository == null) 
       this._contactRepository = new DBRepository<Contact>(context); 
      return _contactRepository; 
     } 
    } 

    public void Save() 
    { 
     context.SaveChanges(); 
    } 

    protected virtual void Dispose(bool disposing) 
    { 
     if (!this.disposed) 
     { 
      if (disposing) 
       context.Dispose(); 
     } 
     this.disposed = true; 
    } 

    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 
} 
+0

詳細な回答ありがとうございます。はい、私はリポジトリを実装するこの方法を知っています。私はちょうどもっと複雑なクエリでさまざまなエンティティを拡張する方法に固執しています:) - 私が目指しているのは、あなたが書いたgen repoクラスと、別々のリポジトリを個別に拡張する方法です。この例のように、カスタムクエリを使用した連絡先リポジトリ:)。私はあなたがこれで行く場所を得ることを願っています:) –

+0

作成時、更新時、削除時には常に汎用ですが、これらのクエリについては何も複雑でなく、リスト操作では式を渡します。ラムダ式をあなたが好きなように複雑にすることができます。もしあなたが本当に別のリポジトリクラスを持っているルートに行きたいなら、是非実行してください。上記の例のようにジェネリックを実装してください。あなたのいわゆる複雑なクエリのための追加のメソッド –

+0

私はあなたのポイントを参照してください。ありがとうございました:) –

関連する問題