Что такое Application слой (уровень приложения) в архитектуре?

«Что такое Application слой (уровень приложения) в архитектуре?» — вопрос из категории Архитектура, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Application слой (уровень приложений) — это слой в многослойной архитектуре (например, Clean Architecture, Onion), который отвечает за координацию рабочих процессов приложения и реализацию сценариев использования (Use Cases). Он служит посредником между внешними интерфейсами (Presentation/UI) и доменной логикой (Domain Layer).

Ключевые обязанности:

  • Оркестрация: Координация вызовов к доменным объектам, репозиториям и внешним сервисам для выполнения конкретного сценария.
  • Транзакционность: Управление границами транзакций для операции.
  • Валидация входных данных: Проверка DTO (Data Transfer Objects) на корректность с точки зрения приложения.
  • Преобразование данных: Маппинг между доменными моделями и DTO для ввода/вывода.

Пример Application Service на C#:

public class PlaceOrderService // Application Service
{
    private readonly IOrderRepository _orderRepository;
    private readonly IInventoryClient _inventoryClient;

    public PlaceOrderService(IOrderRepository orderRepository, IInventoryClient inventoryClient)
    {
        _orderRepository = orderRepository;
        _inventoryClient = inventoryClient;
    }

    public async Task<OrderResultDto> Execute(PlaceOrderCommand command)
    {
        // 1. Валидация входных данных (Application concern)
        if (command.Items == null || !command.Items.Any())
            throw new InvalidRequestException("Order must contain items.");

        // 2. Координация доменной логики и инфраструктуры
        var productIds = command.Items.Select(i => i.ProductId).ToList();
        var areAvailable = await _inventoryClient.CheckAvailability(productIds);
        if (!areAvailable)
            throw new DomainException("Products are out of stock.");

        // 3. Создание и сохранение доменного агрегата (Domain concern)
        var order = new Order(command.CustomerId);
        foreach (var item in command.Items)
        {
            order.AddItem(item.ProductId, item.Quantity);
        }

        await _orderRepository.AddAsync(order);
        await _orderRepository.UnitOfWork.SaveChangesAsync(); // Управление транзакцией

        // 4. Возврат DTO (Application concern)
        return new OrderResultDto { OrderId = order.Id, Status = order.Status };
    }
}

Важно: Application слой не содержит сложной бизнес-логики (это Domain Layer) и инфраструктурных деталей (доступ к БД, вызов API — это Infrastructure Layer).