我是一名 C# 开发人员,但我几乎阅读了所有关于 cqrs 的教程,不管语言是否是 Java,因为我想学习 cqrs 的结构和基础。
但现在我认为,我阅读了这么多教程的事实是问题所在,因为教程之间存在差异,现在我很困惑,不知道我必须使用哪种技术。
两个主要问题在我的脑海中肆虐,也许你们中的一些人可以在那里澄清一些问题。
在命令方面,例如,我应该在哪里放置调用我的 ORM 的逻辑?有些教程在命令处理程序中执行此操作(对我来说更符合逻辑),有些教程在事件处理程序中执行此操作,该事件处理程序将由命令处理程序触发,在这种情况下,仅执行验证逻辑。
对于事件存储和撤消认为,我必须将哪些数据保存到数据库中,一些教程保存聚合,一些保存事件模型。
我希望有人可以解释我要使用什么模式以及为什么,也许两者都在不同的场景中,我不知道。
一个实际的例子会很棒。(仅伪代码)
可能是用户注册,RegisterTheUser 命令:
要做的事情:
- 检查用户名是否已被使用
- 将用户添加到数据库
- 发送确认邮件(在命令中还是在 UserIsRegistered 事件中?)
- 触发事件 ConfirmationMailSended 还是仅触发 UserIsRegistered 事件?
亲切的问候
编辑:这是我当前的实现(简单)
public class RegisterTheUser : ICommand
{
public String Login { get; set; }
public String Password { get; set; }
}
public class RegisterTheUserHandler : IHandleCommand<RegisterTheUser, AccountAggregate>
{
public void Handle(AccountAggregate agg, RegisterTheUser command)
{
if (agg.IsLoginAlreadyInUse(command.Login))
throw new LoginIsAlreadyInUse();
agg.AddUserAccount(command);
CommandBus.Execute<SendMail>(x => { });
EventBus.Raise<UserIsRegistred>(x => { x.Id = agg.UserAccount.Id; });
}
}
public class UserIsRegistred : IEvent
{
public Guid Id { get; set; }
}
public class AccountAggregate : AggregateBase
{
public AccountAggregate(IUnitOfWork uow)
{
UnitOfWork = uow;
}
private IUnitOfWork UnitOfWork { get; set; }
public UserAccount UserAccount { get; set; }
public void AddUserAccount(RegisterTheUser command)
{
UserAccount = new UserAccount
{
Id = Guid.NewGuid(),
IsAdmin = false,
Login = command.Login,
Password = Crypto.Sha512Encrypt(command.Password)
};
UnitOfWork.UserAccountRepository.Add(UserAccount);
UnitOfWork.Commit();
}
public Boolean IsLoginAlreadyInUse(String login)
{
var result = UnitOfWork.UserAccountRepository.SingleOrDefault(x => x.Login == login);
return (result != null);
}
}