agentsclimarketplace

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

Install
npx -y skills add luismpenholato/maurao-skills --skill dotnet-backend-clean-architecture

Assembled 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

TechnologyUsage
.NET 10Runtime and SDK (net10.0, SDK 10.0.301+)
MediatR 14CQRS
FluentValidation 12Validation in handler
EF Core 10ORM (InMemory / SQL Server)
FluentMigrator 8SQL schema (not EF Migrations)
Refit 11 + Http.Resilience 10HTTP integrations
xUnit + NSubstitute + FluentAssertionsUnit 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.cs implementing IEntity<TKey> (e.g., long).
  • Interfaces/Repositories/IOrderRepository.cs extending ICrudRepository<Order, long>.
  • Interfaces/UnitOfWork/IOrderUnitOfWork.cs with repository + SaveChangesAsync.

CrossCutting

  • Dto/Orders/OrderDto.cs (and other API DTOs if needed).

Infrastructure

  • Persistence/Map/OrderEntityConfig.cs (EF Fluent API).
  • DbSet<Order> in AppDbContext.
  • Repositories/OrderRepository.cs extending RepositoryBase<Order, long>.
  • UnitOfWork/OrderUnitOfWork.cs implementing IOrderUnitOfWork.
  • CrossCutting.IOC: register in ConfigureBindingsRepository and ConfigureBindingsUnitOfWork.

Application – Commands

  • Folder Features/Orders/Commands/CreateOrder/.
  • CreateOrderCommand.cs: record with : IRequest<OrderDto>.
  • CreateOrderHandler.cs: inject IOrderUnitOfWork and IValidator<T>; ValidateAndThrowAsync at 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; mock IValidator<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:

  1. CrossCutting: integration DTOs (e.g., ExternalProductDto), Options/ExternalProductApiOptions.cs.
  2. Domain: Interfaces/Integration/IExternalProductIntegration.cs (Refit) and Interfaces/Services/IExternalProductService.cs.
  3. Domain/Services: implementation that translates Refit exceptions (e.g., 404 → null).
  4. CrossCutting.IOC: ConfigureBindingsIntegrationAddRefitClient<T>() + AddStandardResilienceHandler().
  5. 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; only Mediator.Send.

Error handling

  • FluentValidation → ValidationException → global middleware → 400 ProblemDetails.
  • Business rules → InvalidOperationException → 400.
  • Other exceptions → 500 (generic message in production).
  • Middleware: GlobalExceptionMiddleware in Interface.

Anti-patterns

  • Global ValidationBehavior instead of explicit ValidateAndThrowAsync in 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/ValidationBehavior in this pattern — validation stays in the handler.
  • Formatting: dotnet format {Solution}.sln (.editorconfig).

Additional resources

What ships with it: 1 file

4.9 KB alongside SKILL.md

Keep looking

Skills are one crate of 326,852. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.