Ответ 1
Обычный способ структурирования приложения 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));
}
}