- Use `IRequest<TResponse>` for commands/queries and `IRequestHandler<TRequest, TResponse>` for handlers — one handler per request type.
- Use `INotification` for events that have multiple handlers — publish with `IMediator.Publish()` for fan-out processing.
- Use pipeline behaviors (`IPipelineBehavior<TRequest, TResponse>`) for cross-cutting concerns: validation, logging, transaction management.
- Use `INotification` and `INotificationHandler` for event broadcasting to multiple handlers.
- Use pipeline behaviors (`IPipelineBehavior<TReq, TRes>`) for cross-cutting concerns: logging, validation, caching.
- Keep one handler per file. Name handlers after the request: `CreateUserCommandHandler`.
- Register MediatR in DI: `services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(...))`.