Я использую в своем проекте DDD / CQRS следующий подход, структура проекта - уровень API, уровень домена, уровень доступа к данным, все входные данные из пользовательского интерфейса или от пользователя проверяются до того, как команда создается и отправляется, чтобы обновитьсостояние домена, и мы проверяем входные данные, когда один из них находится на пользовательском интерфейсе (приложение Angular), а второй - на уровне веб-API, если данные действительны, команда CQRS создается и отправляется после того, как вы можете провести проверку бизнес-логики.,Для проверки вы можете использовать FastValidator или FluentValidation
ОБНОВЛЕНИЕ: Вот простой пример, у нас есть API для создания пакетного объекта.
[HttpPost]
[Route("create")]
public IHttpActionResult Create([FromBody] BatchEditModel model)
{
var createCommand = model.Map<BatchEditModel, CreateBatchCommand>();
var result = (OperationResult<int>) _commandDispatcher.Dispatch(createCommand);
return Result(result);
}
Как вы можете видеть, пользовательские входные данные будут BatchEditModel
.
, поэтому у нас есть BatchEditModelValidator
, который содержит проверку входных данных:
public class BatchEditModelValidator : AbstractValidator<BatchEditModel>
{
public BatchEditModelValidator()
{
RuleFor(x => x.Number).NotEmpty()
.WithMessage(ValidatorMessages.MustBeSpecified);
RuleFor(x => x.ClientId).GreaterThan(0)
.WithMessage(ValidatorMessages.MustBeSpecified);
RuleFor(x => x.EntryAssigneeId).GreaterThan(0)
.WithMessage(ValidatorMessages.MustBeSpecified);
RuleFor(x => x.ReviewAssigneeId).GreaterThan(0)
.WithMessage(ValidatorMessages.MustBeSpecified);
RuleFor(x => x.Description).NotEmpty()
.WithMessage(ValidatorMessages.MustBeSpecified);
}
}
, этот валидатор будет выполнен до того, как BatchEditModel будетсопоставлены с CreateBatchCommand
и в CreateBatchCommandHandler
у нас есть проверка бизнес-логики CheckUniqueNumber
public OperationResult Handle(CreateBatchCommand command)
{
var result = new OperationResult<int>();
if (CheckUniqueNumber(result, command.ClientId, command.Number))
{
if (result.IsValid)
{
var batch = _batchFactory.Create(command);
_batchRepository.Add(batch);
_batchRepository.Save();
result.Value = batch.Id;
}
}
return result;
}