我们说我有一个命令处理程序:
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}}。
哪种方法更好?
谢谢!
答案 0 :(得分:1)
我实施的设置与ddd-cqrs-sample非常相似。这是&#34;运行环境&#34;的课程。负责使用相应的命令处理程序运行命令。除此之外,我的RE实现了事务边界。它负责启动一个工作单元,并在命令执行后执行提交/回滚,具体取决于命令的结果。
当然这取决于您的使用案例。如果您的命令行为大致相同,那么您的调用类可能构成事务边界。我认为在大多数情况下,应该尝试建立这样的命令设计,以便使命令简单并专注于一项任务。