A dotnet new template for creating ASP.NET services using the Trellis framework with Railway-Oriented Programming (ROP) and Domain-Driven Design (DDD).
dotnet new install Trellis.AspTemplatedotnet new trellis-asp -n MyService --authorName "Your Name"This creates a MyService/ directory with the full solution structure ready to build and run.
cd MyService
dotnet build
dotnet testdotnet run --project Api/srcThe template provides a layered architecture following DDD and CQRS principles:
| Layer | Project | Purpose |
|---|---|---|
| Domain | Domain/ |
Aggregates, entities, value objects — pure business logic with zero external dependencies |
| Application | Application/ |
Commands, queries, handlers — orchestrates domain logic via CQRS (Mediator) |
| Anti-Corruption Layer | Acl/ |
Repository implementations, external service adapters, EF Core — shields the domain from infrastructure |
| API | Api/ |
Controllers, DTOs, middleware, composition root — thin HTTP layer |
Each layer has src/ and tests/ projects.
- Railway-Oriented Programming — Errors are values (
Result<T>), not exceptions. Business logic flows through composable pipelines usingBind,Map,Ensure, andTap. - Domain-Driven Design — Value objects with
TryCreatevalidation, aggregates with domain events, specifications for composable queries. - CQRS — Commands and queries separated via Mediator source generator.
- Service Level Indicators — All API methods emit duration and status code metrics via ServiceLevelIndicators.
- OpenTelemetry — Traces and metrics configured out of the box. Use the included Aspire Dashboard for local observability.
- API Versioning — Date-based versioning with
Asp.Versioning. - Copilot Instructions —
.github/copilot-instructions.mdand.github/trellis-api-reference.mdguide AI assistants to follow Trellis patterns.
| Parameter | Description | Default |
|---|---|---|
-n / --name |
Service name (used for solution file, namespaces, assembly names) | MyService |
--authorName |
Author name in Directory.Build.props |
Your Name |
When deploying across multiple regions and environments, set RegionShortName and Environment to derive resource names automatically via EnvironmentOptions:
{
"EnvironmentOptions": {
"Environment": "test",
"Region": "westus2",
"RegionShortName": "usw2"
}
}