Ответ
Да, в референсной архитектуре eShopOnContainers явно выделен Application слой. Он находится между Presentation (веб-API) и Domain слоями и реализует Use Cases (сценарии использования) приложения.
Роль и обязанности Application слоя в eShop:
- Оркестрация потока выполнения: Координация работы Domain-объектов (сущностей, агрегатов) и Infrastructure-сервисов для выполнения конкретной бизнес-операции.
- Работа с DTO (Data Transfer Objects): Преобразование Domain-моделей в объекты, удобные для передачи через API, и наоборот. Важно: В этом слое нет бизнес-правил.
- Валидация команд: Проверка входных данных на корректность формата (например, с помощью FluentValidation) перед передачей в Domain.
- Управление транзакциями: Обеспечение целостности одной бизнес-операции, часто через Unit of Work.
- Публикация Domain Events: После успешного выполнения операции слой Application может публиковать события для уведомления других частей системы.
Пример из eShopOnContainers (Application Service):
// Ordering.API.Application.Commands.CreateOrderCommandHandler
public class CreateOrderCommandHandler
: IRequestHandler<CreateOrderCommand, bool>
{
private readonly IOrderRepository _orderRepository;
private readonly IIdentityService _identityService;
private readonly IMediator _mediator;
public async Task<bool> Handle(CreateOrderCommand command, CancellationToken cancellationToken)
{
// 1. Создание Domain-объекта (Агрегата Order) на основе команды
var address = new Address(...);
var order = new Order(command.UserId, command.UserName, address, command.CardTypeId, ...);
foreach (var item in command.OrderItems)
{
order.AddOrderItem(item.ProductId, item.ProductName, ..., item.Units);
}
// 2. Сохранение агрегата через Repository (инфраструктура)
_orderRepository.Add(order);
// 3. Сохранение изменений (Unit of Work)
var result = await _orderRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);
// 4. Публикация Domain Event через Mediator
// (например, OrderStartedDomainEvent для запуска Saga оплаты)
await _mediator.Publish(new OrderStartedDomainEvent(order), cancellationToken);
return result;
}
}
Этот обработчик команды — типичный компонент Application слоя: он получает команду CreateOrderCommand (DTO), использует Domain-логику для создания заказа, сохраняет его и публикует событие.