Repository Pattern Standardization of methods

前端 未结 7 1569
天涯浪人
天涯浪人 2021-01-30 02:05

All I am trying to find out the correct definition of the repository pattern.

My original understanding was this (extremely dumbed down)

  • Separate your Busi
相关标签:
7条回答
  • 2021-01-30 02:17

    In addition to your generic repository interface (implementation 1) and your variation on the role-specific repository (implementation 2) you can also consider a generic method repository:

    public interface IRepository
    {
        void Save<ENTITY>(ENTITY entity) where ENTITY : DomainEntity;
    
        ENTITY Load<ENTITY>(Guid id) where ENTITY : DomainEntity;
    
        IQueryable<ENTITY> Query<ENTITY>() where ENTITY : DomainEntity;
    
        IQueryable<ENTITY> Query<ENTITY>(IDomainQuery<ENTITY> whereQuery)
            where ENTITY : DomainEntity;
    }
    

    This third version comes from this blogpost by Jimmy Bogard, where he also expresses preference for the generic repository interface. I usually follow that with a generic repository baseclass which implements this interface; that way, I only have to implement the stuff that is different for each domain entity.

    0 讨论(0)
  • 2021-01-30 02:19

    I usually use the generic repository with composition instead of inheritance. That gives me the advantage of a generic implementation, with the control of which methods to expose.

    Something like this:

    public Interface IRepository<T>{
      List<T> GetAll();
      void Create(T p);
      void Update(T p);
    }
    
    
    public interface IProductRepository {
      //Extension methods if needed
       List<Product> GetProductsByCustomerID();
       List<T> GetAll();
       void Create(T p);
       //Let assume here you should not be able to update the products
    }
    
    public ProductRepository : IProductRepository {
        private IRepository _repository;
    
        public ProductRepository(IRepository repository) {
            this._repository = repository;
        }
    
           List<T> GetAll() 
           {
                _repository.GetAll();
           }
    
           void Create(T p) 
           {
                _repository.Create(p);
           }
    
           List<Product> GetProductsByCustomerID() 
           {
              //..implementation goes here
           }
    }
    
    0 讨论(0)
  • 2021-01-30 02:20

    I second the Fowler quote cited by oded. I want to point out that he said "collection-like" interface. How you implement the collection like interface is certainly up to you, but neither can nor should you try to hide the fact it represents a remote datasource. It therefore differs significantly from an in-memory collection, which does not need to flush changes to a remote data store. The change tracking mechanism of your ORM or your roll-your-own solution determines how transparent this can be made to the caller. Deletes usually need to be marked explicitly, inserts are discoverable (persistence by reachability) and updates sometimes need to be marked explicitly too. Combine this with the complicated dependencies of your aggregate roots and you'll see that's not very collection like.

    There is no such thing as "the cannonical repository implementation".

    There is a constant battle going on between the advocators of a generic repository base class and those who prefer implementing each repository on its own. While the generic implementation is appealing in simple scenarios, you will very often find it to be a very leaky abstraction. For example some of your aggregates may only be soft-deleted (cistomizable via virtual method overrides) while others may not support a delete operation at all.

    Make sure you understand the implications of each approach before deciding which route to take. Greg Young has a good post on the merits of generic repositories.

    http://codebetter.com/blogs/gregyoung/archive/2009/01/16/ffffd-the-generic-repository.aspx

    0 讨论(0)
  • 2021-01-30 02:23

    The repository pattern is one of the most used pattern in software development. The are many post that can be marked as answer to your question. Something that i like to highlight is the fact that a good repository implementation will be improved if you use IoC (Autofac, Windsor, etc...). I have been playing long time ago with some ADO.NET based frameworks (LinqToSql, EF) and NHibernate. You always can have benefits from a generic implementation if you use IoC. You can define interfaces for your specific repositories and resolve when you really need some specific actions.

    0 讨论(0)
  • 2021-01-30 02:27

    From Martin Fowler "Patterns of Enterprise Application Architecture", the definition of the Repository Pattern is:

    Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.

    So, both approaches are correct.

    0 讨论(0)
  • 2021-01-30 02:33

    With the introduction of LINQ in .NET, a generic repository pattern becomes much easier to realize:

    public interface IRepository<T> : IQueryable<T>
    {
        void Add(T item);
        void Remove(T item);
    }
    

    To qualify as a repository, it merely needs to be able to access data in the underlying store (easily provided by IQueryable) and modify the contained data.

    You can provide extensions to the base interface to provide hooks for more entity-specific behaviour (such as wiring into a stored procedure call for a SQL-based repository), but the majority of operations can be completed by the simple interface.

    0 讨论(0)
提交回复
热议问题