CQRS:ICommandHandler <tcommand>是否应该负责在IUnitOfWork上调用SaveChanges()?</tcommand>

时间:2014-05-13 05:52:40

标签: unit-of-work cqrs

我们说我有一个命令处理程序:

public class AddNewUserCommandHandler : ICommandHandler<AddNewUserCommand>
{
    //IUserManagementUnitOfWork implements IUnitOfWork.SaveChanges()
    //hold references to related repositories
    //basically an abstraction over DbContext/DbSet
    private IUserManagementUnitOfWork uow; 

    public AddNewUserCommandHandler(IUserManagementUnitOfWork uow)
    {
        this.uow = uow;
    }

    public void Handle(AddNewUserCommand command)
    {
        var user = new User
        {
            FirstName = command.FirstName,
            LastName = command.LastName
        };
        uow.UserRepository.Add(user);
        uow.SaveChanges(); //should this be here?
        command.UserId = user.Id;
    }
}

我的问题是:ICommandHandler<TCommand>是否有责任在SaveChanges()上致电IUnitOfWork?或者这应该是来电者的责任吗?

例如,AddNewUserCommandHandler只有IRepository<User>作为其依赖关系,调用方将保留对IUnitOfWork的引用,并在感觉到它时调用SaveChanges() 。调用者可能是ICommandProcessor,可以处理多个ICommand并在其处理程序成功处理所有命令时调用SaveChanges

或者,将SaveChanges()职责留给ICommandHandler<TCommand>并将批处理命令处理器包装在TransactionScope中,并将command.UserId = user.Id委托给将在调用后执行的事件{ {1}}。

哪种方法更好?

谢谢!

1 个答案:

答案 0 :(得分:1)

我实施的设置与ddd-cqrs-sample非常相似。这是&#34;运行环境&#34;的课程。负责使用相应的命令处理程序运行命令。除此之外,我的RE实现了事务边界。它负责启动一个工作单元,并在命令执行后执行提交/回滚,具体取决于命令的结果。

当然这取决于您的使用案例。如果您的命令行为大致相同,那么您的调用类可能构成事务边界。我认为在大多数情况下,应该尝试建立这样的命令设计,以便使命令简单并专注于一项任务。