简体   繁体   English

工作单元和存储库模式

[英]Unit of Work and Repository Pattern

I would like to implement simple IGenericRepository and IUnitOfWork interfaces in my application but I'm not sure whats the best way to do it.我想在我的应用程序中实现简单的 IGenericRepository 和 IUnitOfWork 接口,但我不确定最好的方法是什么。

As far as I could understand, UnitOfWork should be used for writing, while Repository should be used for reading.据我所知,UnitOfWork应该用于写作,而Repository应该用于阅读。 I have encountered one architecture and I really like it, but I only found interfaces and not the implementations, and I'm not sure how should I implement those.我遇到过一种架构并且我真的很喜欢它,但我只找到了接口而不是实现,我不确定我应该如何实现它们。

public interface IGenericRepository : IDisposable
{
    IUnitOfWork CreateUnitOfWork();
    T FirstOrDefault<T>(Expression<Func<T, bool>> predicate) where T : class, IBaseEntity;
    IQueryable<T> Get<T>(Expression<Func<T, bool>> predicate = null, Func<IQueryable<T>, IOrderedQueryable<T>> sorter = null, params string[] includeProperties) where T : class, IBaseEntity;
    IQueryable<T> GetAll<T>() where T : class, IBaseEntity;
    IDbContext GetDbContext();
}

public interface IUnitOfWork : IDisposable
{
    int Commit();
    bool Delete<T>(T entity) where T : class, IBaseEntity;
    int DeleteItems<T>(IList<T> entities) where T : class, IBaseEntity;
    bool Insert<T>(T entity) where T : class, IBaseEntity;
    int InsertItems<T>(IList<T> entities) where T : class, IBaseEntity;
    bool Update<T>(T entity) where T : class, IBaseEntity;
    int UpdateItems<T>(IList<T> entities) where T : class, IBaseEntity;
}

I'm not sure how should those work.我不确定这些应该如何工作。 Should I use IDbContextFactory within repository to share DbContext between Repository and UnitOfWork or they should have separate DbContexts?我应该在存储库中使用 IDbContextFactory 在 Repository 和 UnitOfWork 之间共享 DbContext 还是应该有单独的 DbContexts? If I implement UnitOfWork for write and Repository for read, should there be UnitOfWorks DbContext for write and Repositorys DbContext for read or they should share same DbContext?如果我实现 UnitOfWork 用于写入和 Repository 用于读取,是否应该有用于写入的 UnitOfWorks DbContext 和用于读取的 Repositorys DbContext 还是它们应该共享相同的 DbContext?

I would really appreciate good explanation of how DbContext and UnitOfWork/Repository should work.我非常感谢 DbContext 和 UnitOfWork/Repository 应该如何工作的良好解释。

Those would be implemented in service in such way:这些将以这种方式在服务中实施:

public CustomerService(IGenericRepository repository)
{
    this.repository = repository;
    this.context = this.repository.GetDbContext();
}

public void UpdateCustomer(Customer customer)
{
    var uow = this.repository.CreateUnitOfWork();
    uow.AddForSave(customer);
    uow.Commit();
}

public List<Customer> GetAll()
{
    return this.repository.GetAll<Customer>();
}

Any help, explanation about DbContext and UoW/Repository relation, or good tutorial similar to this implementation would help.任何帮助、关于 DbContext 和 UoW/Repository 关系的解释,或者类似于这个实现的好教程都会有所帮助。

Regards.问候。

I think this is what you need. 我认为就是您所需要的。 All your tags in one article ) 一篇文章中的所有标签)

I would like to recommend that you avoid the Repository pattern, for inserts/updates.对于插入/更新,我建议您避免使用 Repository 模式。

You should consider "command/query objects" as an alternative, you can find a bunch of interesting articles around this area, but here is a good one:您应该考虑将“命令/查询对象”作为替代方案,您可以在该领域找到一堆有趣的文章,但这里有一篇很好的文章:

https://rob.conery.io/2014/03/03/repositories-and-unitofwork-are-not-a-good-idea/ https://rob.conery.io/2014/03/03/repositories-and-unitofwork-are-not-a-good-idea/

You would stick to a single command object per command to enable simple transactions, avoiding the need for the complexity of the Unit Of Work pattern.您将坚持每个命令使用一个命令对象来启用简单的事务,从而避免工作单元模式的复杂性。

However, if you are thinking a Query object per query is overkill, this would often be right.但是,如果您认为每个查询一个 Query 对象是矫枉过正,这通常是正确的。 Instead you might choose to start with a 'FooQueries' object, which is essentially a Repository but only for Queries.相反,您可以选择从“FooQueries”对象开始,它本质上是一个存储库,但仅用于查询。 'Foo' might be your 'domain aggregate' in the DDD sense. 'Foo' 可能是 DDD 意义上的“域聚合”。

Later, you might find splitting out individual query objects worthwhile if you want to add cross cutting concerns via attributes, you could even feed a query object into a pipeline.稍后,如果您想通过属性添加横切关注点,您可能会发现拆分单个查询对象是值得的,您甚至可以将查询对象输入到管道中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM