From dotnet
Best practices for .NET application architecture based on Domain-Driven Design (DDD), SOLID principles, and layered architecture. Covers aggregate design, value objects, domain events, bounded contexts, domain services, application services, repository patterns, specification patterns, and infrastructure concerns. Includes testing standards (unit, integration, acceptance) with minimum coverage targets, step-by-step implementation workflows, and financial domain considerations (monetary value handling, saga patterns, audit trails, regulatory compliance). Apply this skill whenever designing, building, reviewing, or refactoring .NET application architecture -- including when the user mentions domain models, aggregates, bounded contexts, domain events, layered architecture, SOLID violations, repository patterns, or DDD concepts, even if they do not explicitly say "architecture."
npx claudepluginhub atc-net/atc-agentic-toolkit --plugin dotnetThis skill uses the workspace's default tool permissions.
Apply these practices when designing, building, reviewing, or refactoring .NET applications that benefit from structured domain modeling and layered architecture.
Implements Domain-Driven Design tactical patterns for .NET: aggregates, roots, value objects, domain events, services, typed IDs, repositories. For DDD aggregates, events, bounded contexts.
Modeling business domains. Aggregates, value objects, domain events, rich models, repositories.
Guides Domain-Driven Design for complex business logic: aggregates, bounded contexts, ubiquitous language, value objects, entities, and TypeScript implementations with invariants.
Share bugs, ideas, or general feedback.
Apply these practices when designing, building, reviewing, or refactoring .NET applications that benefit from structured domain modeling and layered architecture.
DDD aligns software design with business reality. The goal is to make the codebase a direct expression of business concepts, so domain experts and developers share a common vocabulary and the system remains adaptable as the business evolves.
Order -- not PurchaseRecord or TransactionItem. This reduces translation errors and keeps the model honest.OrderPlaced, PaymentReceived). Domain events decouple bounded contexts, enable audit trails, and support eventual consistency across service boundaries.For detailed patterns including aggregate design rules, value object implementation, and domain event handling, see references/domain-layer.md.
These principles guide class and module design toward code that is easier to understand, extend, and test.
PremiumCustomer extends Customer, any code that works with Customer should work identically with PremiumCustomer.IOrderService into IOrderReader and IOrderWriter if some consumers only need read access.async/await throughout the stack. Avoid blocking calls (.Result, .Wait()) that risk deadlocks and thread pool starvation.Scoped for per-request, Singleton for stateless services, Transient for lightweight disposable objects).IQueryable<T> to push filtering to the database.required properties to reduce boilerplate and catch errors at compile time.Organize code into layers with clear dependency direction: outer layers depend on inner layers, never the reverse.
A typical service repository contains:
src/
MyService.Api/ # Minimal API host, endpoints, middleware
MyService.Domain/ # Business logic, aggregates, command handlers, processors
MyService.Events/ # Domain event definitions (shared as NuGet package)
MyService.Api.Contracts/ # API request/response DTOs (shared as NuGet package)
MyService.Api.Client/ # Generated typed HTTP client for consumers
MyService.Functions/ # Azure Functions for event-driven processing (optional)
MyService.AppHost/ # Aspire orchestration (optional)
test/
MyService.Domain.Tests/
MyService.Api.Tests/
This structure separates publishable contracts (Events, Api.Contracts, Api.Client) from internal implementation (Domain, Api). Other services depend on the contracts packages, not the implementation.
The heart of the application. Contains business logic with zero dependencies on infrastructure or frameworks.
Money, EmailAddress)For detailed domain layer patterns, see references/domain-layer.md.
Thin orchestration layer that wires up the domain and exposes it via HTTP:
app.MapEndpoints() over MVC controllersIServiceCollectionFor detailed application and infrastructure patterns, see references/application-infrastructure.md.
Concrete implementations injected via DI:
ICosmosReader<T> / ICosmosWriter<T> for Cosmos DB (via Atc.Cosmos), or EF Core repositories for relational databasesFor detailed infrastructure patterns, see references/application-infrastructure.md.
Many .NET services use event sourcing with CQRS as their core architectural pattern:
DeviceView from device events)ICommandProcessorFactory dispatches commands to the correct handler without MediatRWell-structured tests protect domain invariants and enable confident refactoring. Use the test naming convention established in the project — common patterns include Should_<Expected>_When_<Condition> or MethodName_Condition_ExpectedResult.
[AutoNSubstituteData] (from Atc.Test) with [Frozen] for automatic mock injection. Use FluentAssertions for assertions.For detailed testing guidance, see references/testing.md.
When building or refactoring a feature, follow this sequence to ensure architectural alignment.
Financial systems have stricter requirements around precision, auditability, and compliance. When working in a financial context, apply these additional practices.
For detailed financial domain guidance, see references/financial-domain.md.
Key points:
decimal for all monetary values -- never float or double, which introduce rounding errors