工作单元 + 存储库模式:业务交易概念的堕落 [英] Unit of Work + Repository Pattern: The Fall of the Business Transaction Concept

查看:26
本文介绍了工作单元 + 存储库模式:业务交易概念的堕落的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

结合工作单元存储库模式是当今使用相当广泛的东西.正如 Martin Fowler 所说,使用 UoW 的目的是形成一个 <强>业务交易,同时不知道存储库的实际工作方式(持续无知).我已经审查了许多实现;并忽略具体细节(具体/抽象类、接口等),它们或多或少类似于以下内容:

Combining Unit of Work and Repository Pattern is something used fairly widely nowadays. As Martin Fowler says a purpose of using UoW is to form a Business Transaction while being ignorant of how repositories actually work (being persistent ignorant). I've reviewed many implementations; and ignoring specific details (concrete/abstract class, interface,...) they are more or less similar to what follows:

public class RepositoryBase<T>
{
    private UoW _uow;
    public RepositoryBase(UoW uow) // injecting UoW instance via constructor
    {
       _uow = uow;
    }
    public void Add(T entity)
    {
       // Add logic here
    }
    // +other CRUD methods
}

public class UoW
{
    // Holding one repository per domain entity

    public RepositoryBase<Order> OrderRep { get; set; }
    public RepositoryBase<Customer> CustomerRep { get; set; }
    // +other repositories

    public void Commit()
    {
       // Psedudo code: 
       For all the contained repositories do:
           store repository changes.
    }
}

现在我的问题:

UoW 公开公共方法 Commit 来存储更改.此外,因为每个存储库都有一个 UoW 的共享实例,每个 Repository 都可以访问 UoW 上的方法 Commit.通过一个存储库调用它会使所有其他存储库也存储它们的更改;因此,整个交易概念崩溃的结果:

UoW exposes public method Commit to store the changes. Also, because each repository has a shared instance of UoW, each Repository can access method Commit on UoW. Calling it by one repository makes all other repositories store their changes too; hence the result the whole concept of transaction collapses:

class Repository<T> : RepositoryBase<T>
{
    private UoW _uow;
    public void SomeMethod()
    {
        // some processing or data manipulations here
        _uow.Commit(); // makes other repositories also save their changes
    }
}

我认为这一定是不允许的.考虑到 UoW(业务事务)的目的,方法 Commit 应该只公开给发起 业务事务 的人,例如 Business层.令我惊讶的是,我找不到任何解决此问题的文章.在所有这些中 Commit 可以被任何被注入的 repo 调用.

I think this must be not allowed. Considering the purpose of the UoW (business transaction), the method Commit should be exposed only to the one who started a Business Transaction for example Business Layer. What surprised me is that I couldn't find any article addressing this issue. In all of them Commit can be called by any repo being injected.

PS:我知道我可以告诉我的开发人员不要在 Repository 中调用 Commit 但受信任的架构比受信任的开发人员更可靠!

PS: I know I can tell my developers not to call Commit in a Repository but a trusted Architecture is more reliable than trusted developers!

推荐答案

我同意您的担忧.我更喜欢有一个环境工作单元,其中打开工作单元的最外层函数是决定是提交还是中止的函数.调用的函数可以打开一个工作范围单元,如果有,它会自动加入环境 UoW,如果没有,则创建一个新的.

I do agree with your concerns. I prefer to have an ambient unit of work, where the outermost function opening a unit of work is the one that decides whether to commit or abort. Functions called can open a unit of work scope which automatically enlists in the ambient UoW if there is one, or creates a new one if there is none.

我使用的 UnitOfWorkScope 的实现深受 TransactionScope 工作方式的启发.使用环境/范围方法还消除了依赖注入的需要.

The implementation of the UnitOfWorkScope that I used is heavily inspired by how TransactionScope works. Using an ambient/scoped approach also removes the need for dependency injection.

执行查询的方法如下所示:

A method that performs a query looks like this:

public static Entities.Car GetCar(int id)
{
    using (var uow = new UnitOfWorkScope<CarsContext>(UnitOfWorkScopePurpose.Reading))
    {
        return uow.DbContext.Cars.Single(c => c.CarId == id);
    }
}

写入的方法如下所示:

using (var uow = new UnitOfWorkScope<CarsContext>(UnitOfWorkScopePurpose.Writing))
{
    Car c = SharedQueries.GetCar(carId);
    c.Color = "White";
    uow.SaveChanges();
}

请注意,如果这是根(最远的)范围,uow.SaveChanges() 调用只会对数据库进行实际保存.否则,它被解释为同意投票",即允许根范围保存更改.

Note that the uow.SaveChanges() call will only do an actual save to the database if this is the root (otermost) scope. Otherwise it is interpreted as an "okay vote" that the root scope will be allowed to save the changes.

UnitOfWorkScope 的整个实现可在以下位置获得:http://coding.abel.nu/2012/10/make-the-dbcontext-ambient-with-unitofworkscope/

The entire implementation of the UnitOfWorkScope is available at: http://coding.abel.nu/2012/10/make-the-dbcontext-ambient-with-unitofworkscope/

这篇关于工作单元 + 存储库模式:业务交易概念的堕落的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆