Является ли CQRS совместимым с Entity Framework Self Tracking Enities/WCF RIA Services?

CQRS делает много смысла. Однако это кажется взаимоисключающим для подхода использования ORM, который обеспечивает отслеживание изменений. Если у меня есть один "канал" для запросов, чтобы мои объекты были как RO, тогда нет изменений в треке. Если у меня есть еще один канал для команд CUD +, это больше RPC aproach с легкими DTO, а затем отправка самонаблюдающих объектов для объединения на более низком уровне.

Как можно согласовать эти два подхода (CQRS/ORM + STE)?

Ответ 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));
  }
}

Ответ 2

Нужно ли согласовывать эти подходы?

Если вы используете CQRS, зачем вам нужно или хотите отслеживать изменения? Это не похоже на то, что ваши объекты совершают круглые поездки.

В моей текущей реализации клиента у нас есть MongoDB с NoRM на стороне Command и SQL Server 2008 R2 с службами данных WCF на стороне запроса. Нет необходимости в Entity Framework на стороне команды, нет необходимости в отслеживании объектов,... и он прекрасно работает!