- Organize into projects: `Domain` (entities, interfaces), `Application` (use cases, DTOs), `Infrastructure` (EF Core, APIs), `WebApi` (controllers).
- Domain project has zero NuGet dependencies — only core .NET types.
- Use MediatR for CQRS command/query separation within Clean Architecture — handlers live in the Application layer, not in controllers.
- Organize the solution into four projects: `Domain` (entities, interfaces, domain events — zero external NuGet deps), `Application` (use cases, MediatR handlers, DTOs), `Infrastructure` (EF Core `DbContext`, external APIs, email), `WebApi` (controllers, middleware).
- Define repository interfaces in `Domain`: `public interface IUserRepository { Task<User?> GetByIdAsync(Guid id); }` — implement in `Infrastructure` with EF Core; controllers never touch `DbContext` directly.
- Dispatch commands and queries through MediatR: `var result = await _mediator.Send(new CreateUserCommand(request.Name, request.Email));` — handlers in `Application` contain all business logic.
- Map between layers with AutoMapper or manual mappers at boundaries: `CreateUserCommand` → `User` domain entity in the handler; `User` → `UserDto` in the controller response.
- Never import `Infrastructure` from `Domain` or `Application` — dependency injection resolves concrete implementations at the `WebApi` entry point.