Распространенным способом структурирования приложения CQRS является использование модели домена в обработчиках команд.
Вы бы отправили команду DTO, а в обработчике вы бы вызвали методы вваши доменные объекты (вы бы не устанавливали свойства ваших доменных сущностей, так как это основной анти-шаблон).
Методы в ваших доменных объектах будут отвечать за изменение внутреннихсостояние вашего домена.
И в этот момент ваш ORM будет нести ответственность за сохранение изменений внутреннего состояния объектов вашего домена.
Этот способ структурирования приложения CQRS не используетEvent Sourcing, но использует ORM и объекты самоконтроля.
Вот очень упрощенный пример.
public class AccountController
{
[HttpPost]
public ActionResult ChangePreferredStatus(Guid accountId, bool isPreferred)
{
if (isPreferred) {
// in response to user action, our controller commands our application to carry out an operation/state transition
Bus.SendCommand(new MakeAccountPreferredCommand(accountId));
}
}
}
public class MakeAccountPreferredCommandHander : IHandle<MakeAccountPreferredCommand>
{
public void Handle(MakeAccountPreferredCommand command)
{
using (var uow = new UnitOfWork()) {
var account = accountRepository.Get(command.AccountId);
if (account != null) {
// we tell the domain what we want it to do, we DO NOT fiddle with its state
account.MakePreferred();
}
uow.Accept(); // accepting the uow saves any changes to self-tracked entities
}
}
}
public class Account : SelfTrackedEntity
{
private Guid accountId;
private bool isPreferred; // ORM tracked *private* state
public void MakePreferred()
{
// entities are responsible for their own state and changing it
ValidateForMakePreferred();
isPreferred = true;
RaiseEvent(new AccountMadePreferredEvent(accountId));
}
}