Dotnet backend clean architecture
Skill luismpenholato/maurao-skills/skills/dotnet-backend-clean-architecture
Clean Architecture + CQRS (MediatR) for .NET 10 backend APIs. Builds and maintains APIs with vertical slice (Features), Commands/Queries, handlers, validators, repositories, FluentMigrator, Refit integrations. Use when creating or refactoring .NET APIs, adding endpoints, commands, queries, entities, or when the user mentions Clean Architecture, CQRS, or MediatR.From its SKILL.md
npx -y skills add luismpenholato/maurao-skills --skill dotnet-backend-clean-architectureAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
7.2 KB, ~1.7k tokens by cl100k_base, as published. Nobody here has run it
Backend .NET – Clean Architecture + CQRS
Guide for creating and maintaining .NET 10 backends with Clean Architecture, CQRS (MediatR), and Features organization (vertical slice).
When to use
- Add a new feature (new entity + CRUD or operations).
- Add a Command or Query to an existing feature.
- Create Controller, Handler, Validator, Repository, or UnitOfWork.
- Configure HTTP integration (Refit + Http.Resilience).
- Review or refactor code to follow this skill's pattern.
When not to use
- Projects that do not use CQRS or MediatR.
- Simple minimal APIs without layered architecture.
- Codebases that use EF Migrations instead of FluentMigrator.
- Projects that already follow a different, established backend pattern.
Target stack
| Technology | Usage |
|---|---|
| .NET 10 | Runtime and SDK (net10.0, SDK 10.0.301+) |
| MediatR 14 | CQRS |
| FluentValidation 12 | Validation in handler |
| EF Core 10 | ORM (InMemory / SQL Server) |
| FluentMigrator 8 | SQL schema (not EF Migrations) |
| Refit 11 + Http.Resilience 10 | HTTP integrations |
| xUnit + NSubstitute + FluentAssertions | Unit tests |
Solution at backend root: {Solution}.sln and .editorconfig (adjust names to your project).
Project names like CleanStack.* reflect the CleanStack template. In other solutions, adapt prefixes to your naming convention while keeping the same layer boundaries.
Solution structure
{solution-root}/
├── {Solution}.sln
├── .editorconfig
├── {Prefix}.Interface/ # API (Controllers, Program, Middlewares)
├── {Prefix}.Application/ # Features/ → Commands and Queries
├── {Prefix}.Domain/ # Entities, Interfaces, Services
├── {Prefix}.Infrastructure/ # EF Core, Repositories, UnitOfWork
├── {Prefix}.CrossCutting/ # DTOs, Options, Helpers
├── {Prefix}.CrossCutting.IOC/ # ConfigureBindings* (DI)
├── {Prefix}.Migration/ # FluentMigrator (console)
└── {Prefix}.Tests/ # Features/ mirroring Application
Dependency rule: Interface → Application, CrossCutting, CrossCutting.IOC. Application and Infrastructure reference Domain. Application does not reference Infrastructure.
Checklist – New feature (e.g., Orders)
Domain
-
Entities/Order.csimplementingIEntity<TKey>(e.g.,long). -
Interfaces/Repositories/IOrderRepository.csextendingICrudRepository<Order, long>. -
Interfaces/UnitOfWork/IOrderUnitOfWork.cswith repository +SaveChangesAsync.
CrossCutting
-
Dto/Orders/OrderDto.cs(and other API DTOs if needed).
Infrastructure
-
Persistence/Map/OrderEntityConfig.cs(EF Fluent API). -
DbSet<Order>inAppDbContext. -
Repositories/OrderRepository.csextendingRepositoryBase<Order, long>. -
UnitOfWork/OrderUnitOfWork.csimplementingIOrderUnitOfWork. - CrossCutting.IOC: register in
ConfigureBindingsRepositoryandConfigureBindingsUnitOfWork.
Application – Commands
- Folder
Features/Orders/Commands/CreateOrder/. -
CreateOrderCommand.cs:recordwith: IRequest<OrderDto>. -
CreateOrderHandler.cs: injectIOrderUnitOfWorkandIValidator<T>;ValidateAndThrowAsyncat the start; return DTO. -
CreateOrderValidator.cs:AbstractValidator<CreateOrderCommand>when validation is needed.
Application – Queries
- Folder
Features/Orders/Queries/ListOrders/. -
ListOrdersQuery.cs+ListOrdersHandler.cs.
Interface
-
Controllers/OrdersController.cs:[ApiController],IMediator, HTTP returns (Ok, CreatedAtAction, NotFound, NoContent).
Tests
- In
{Prefix}.Tests/Features/Orders/mirroring Application:{Command}HandlerTests.cs/{Query}HandlerTests.cs— NSubstitute; mockIValidator<T>in handlers.{Command}ValidatorTests.cs— real validator +Validate().
-
[Trait("Category", "Orders")].
Migration
- New FluentMigrator class in
{Prefix}.Migration/Migrations/(e.g.,Mig_YYYYMMDDHHMMSS_CreateOrders.cs). - Keep aligned with EF
Persistence/Map/.
External HTTP integration (Products pattern)
When a feature consumes an external API:
- CrossCutting: integration DTOs (e.g.,
ExternalProductDto),Options/ExternalProductApiOptions.cs. - Domain:
Interfaces/Integration/IExternalProductIntegration.cs(Refit) andInterfaces/Services/IExternalProductService.cs. - Domain/Services: implementation that translates Refit exceptions (e.g., 404 → null).
- CrossCutting.IOC:
ConfigureBindingsIntegration—AddRefitClient<T>()+AddStandardResilienceHandler(). - Application: query or command using
IExternalProductService.
Config: ExternalProductApi:BaseUrl in appsettings.
Code patterns
Command (record)
public sealed record CreateProductCommand(
string? Name,
string? Description,
decimal? Price,
bool IsActive = true,
int? ImportFromExternalId = null) : IRequest<ProductDto>;
Handler (explicit validation — no global ValidationBehavior)
public async Task<ProductDto> Handle(CreateProductCommand request, CancellationToken cancellationToken)
{
await _validator.ValidateAndThrowAsync(request, cancellationToken);
// logic + repository via UoW
}
Validator registration (IOC)
services.AddValidatorsFromAssemblyContaining<CreateProductValidator>();
Controller
- One controller per resource; async methods with
CancellationToken; onlyMediator.Send.
Error handling
- FluentValidation →
ValidationException→ global middleware → 400 ProblemDetails. - Business rules →
InvalidOperationException→ 400. - Other exceptions → 500 (generic message in production).
- Middleware:
GlobalExceptionMiddlewarein Interface.
Anti-patterns
- Global
ValidationBehaviorinstead of explicitValidateAndThrowAsyncin handlers. - Application referencing Infrastructure directly.
- EF Migrations mixed with FluentMigrator in the same project.
- Business logic in controllers instead of MediatR handlers.
- Skipping validator or handler unit tests for new commands.
Conventions
- Namespaces:
{Prefix}.Application.Features.{Feature}.Commands.{CommandName}and...Queries.{QueryName}. - One command/query per folder in Commands/ or Queries/.
- API DTOs in CrossCutting.Dto; entities in Domain.
- New bindings in CrossCutting.IOC (
ConfigureBindings*.cs). - Do not use
Application/Common/Behaviors/ValidationBehaviorin this pattern — validation stays in the handler. - Formatting:
dotnet format {Solution}.sln(.editorconfig).
Additional resources
- Detailed structure, endpoints, and flows: reference.md.
What ships with it: 1 file
4.9 KB alongside SKILL.md
- reference.md4.9 KB