# Application Layer (CQRS + MediatR) ## Responsibility Command/query handlers orchestrating domain logic via MediatR pipeline. Sits between API controllers and Domain layer. ## Dependencies - **MediatR**: Command/query dispatch - **FluentValidation**: Request validation via pipeline behavior - **AutoMapper**: Domain ↔ DTO mapping ## Consumers - **API Controllers**: Send commands/queries via `IMediator` - **Integration tests**: Direct handler invocation ## Module Structure ``` Application/ ├── Common/ │ ├── Behaviors/ # MediatR pipeline (validation, logging) │ └── Mappings/ # AutoMapper profiles ├── Features/ # One folder per aggregate │ └── Orders/ │ ├── Commands/ # CreateOrder/, UpdateOrder/ (handler + validator + DTO) │ └── Queries/ # GetOrder/, ListOrders/ └── DependencyInjection.cs # Service registration ``` ## Handler Pattern (Command with Validation) ```csharp public record CreateOrderCommand(string CustomerId, List Items) : IRequest>; public class CreateOrderValidator : AbstractValidator { public CreateOrderValidator(IOrderRepository repo) { RuleFor(x => x.CustomerId).NotEmpty(); RuleFor(x => x.Items).NotEmpty(); } } public class CreateOrderHandler : IRequestHandler> { public async Task> Handle( CreateOrderCommand request, CancellationToken ct) { var order = Order.Create(request.CustomerId, request.Items); // Domain factory await _repo.AddAsync(order, ct); await _unitOfWork.SaveChangesAsync(ct); return Result.Ok(_mapper.Map(order)); } } ``` ## Architectural Boundaries - **NO domain logic in handlers**: Handlers orchestrate, domain objects contain logic - **NO direct DbContext access**: Use repository abstractions - **NO cross-feature references**: Features are independent vertical slices ## Adding a New Feature 1. Create folder under `Features/{Aggregate}/{Commands|Queries}/` 2. Add `Command`/`Query` record implementing `IRequest>` 3. Add `Validator` extending `AbstractValidator` 4. Add `Handler` implementing `IRequestHandler>` 5. Add AutoMapper profile in `Common/Mappings/` if new DTO