This is a template for creating a new project using Clean Architecture, leveraging SSW Rules & SSW's over 30 years of experience developing software in the Microsoft space.
-
π¨
dotnet new
cli template - to get you started quickly -
π Aspire
- Dashboard
- Resource orchestration
- Observability
- Simple dev setup - automatic provisioning of database server, schema, and data
-
π― Domain Driven Design Patterns
- Super Hero Domain
- AggregateRoot
- Entity
- ValueObject
- DomainEvent
-
π Minimal Endpoints - because it's fast & simple. β‘
- Extension methods to ensure consistent HTTP Verbs & Status Codes
-
π OpenAPI/Scalar - easily document your API
-
π Global Exception Handling - it's important to handle exceptions in a consistent way & protect sensitive information
- Transforms exceptions into a consistent format following the RFC7231 memo
-
ποΈ Entity Framework Core - for data access
- Comes with Migrations & Data Seeding
- as per ssw.com.au/rules/rules-to-better-entity-framework/
-
π§© Specification Pattern - abstract EF Core away from your business logic
-
π CQRS - for separation of concerns
-
π¦ MediatR - for decoupling your application
-
π¦ ErrorOr - fluent result pattern (instead of exceptions)
-
π¦ FluentValidation - for validating requests
-
π Strongly Typed IDs - to combat primitive obsession
- e.g. pass
CustomerId
type into methods instead ofint
, orGuid
- Entity Framework can automatically convert the int, Guid, nvarchar(..) to strongly typed ID.
- e.g. pass
-
π Directory.Build.Props
- Consistent build configuration across all projects in the solution
- e.g. Treating Warnings as Errors for Release builds
- Custom per project
- e.g. for all test projects we can ensure that the exact same versions of common packages are referenced
- e.g. XUnit and NSubstitute packages for all test projects
- Consistent build configuration across all projects in the solution
-
βοΈ EditorConfig - comes with the SSW.EditorConfig
- Maintain consistent coding styles for individual developers or teams of developers working on the same project using different IDEs
- as per ssw.com.au/rules/consistent-code-style/
-
π§ͺ Testing
- as per ssw.com.au/rules/rules-to-better-testing/
- Simpler Unit Tests for Application
- No Entity Framework mocking required thanks to Specifications
- as per ssw.com.au/rules/rules-to-better-unit-tests/
- Better Integration Tests
- Using Respawn and TestContainers
- Integration Tests at Unit Test speed
- Test Commands and Queries against a Real database
- No Entity Framework mocking required
- No need for In-memory database provider
- Architecture Tests
- Using NetArchTest
- Know that the team is following the same Clean Architecture fundamentals
- The tests are automated so discovering the defects is fast
- Docker / Podman
- Dotnet 9
- .NET Aspire CLI (optional)
-
Install the SSW CA template
dotnet new install SSW.CleanArchitecture.Template
Note
The template only needs to be installed once. Running this command again will update your version of the template.
-
Create a new directory
mkdir Northwind365 cd Northwind365
-
Create a new solution
dotnet new ssw-ca
Note
name
is optional; if you don't specify it, the directory name will be used as the solution name and project namespaces.
Alternatively, you can specify the name
and output
directory as follows:
dotnet new ssw-ca --name {{SolutionName}} --output .\
-
Create a query
cd src/Application/UseCases mkdir {{FeatureName}} cd {{FeatureName}} dotnet new ssw-ca-query --name {{QueryName}} --entityName {{Entity}} --slnName {{SolutionName}}
-
Create a command
cd src/Application/UseCases mkdir {{FeatureName}} cd {{FeatureName}} dotnet new ssw-ca-command --name {{CommandName}} --entityName {{Entity}} --slnName {{SolutionName}}
-
Change directory
Windows:
cd tools\AppHost\
Mac/Linux:
cd tools/AppHost/
-
Run the solution
dotnet run
Note
The first time you run the solution, it may take a while to download the docker images, create the DB, and seed the data.
- Open https://localhost:7255/scalar/v1 in your browser to see it running οΈπββοΈ
Due to .NET Aspire orchestrating the application startup and migration runner, EF migrations need to be handled a little differently to normal.
Adding new migrations is still the same old command you would expect, but with a couple of specific parameters to account for the separation of concerns. This can be performed via native dotnet tooling or through the Aspire CLI:
- Run either of following commands from the root of the solution.
dotnet ef migrations add YourMigrationName --project ./src/Infrastructure/Infrastructure.csproj --startup-project ./src/WebApi/WebApi.csproj --output-dir ./Persistence/Migrations
aspire exec --resource api -- dotnet ef migrations add YourMigrationName --project ../Infrastructure/Infrastructure.csproj --output-dir ./Persistence/Migrations
.NET Aspire handles this for you - just start the project!
This is where things need to be done a little differently and requires the Aspire CLI.
- Enable the
exec
function:
aspire config set features.execCommandEnabled true
- Pass the EF migration shell command through Aspire from the root of the solution:
aspire exec --resource api -- dotnet ef migrations remove --project ..\Infrastructure --force
Note
The --force
flag is needed because .NET Aspire will start the application when this command is run, which triggers the migrations to run. This will apply your migrations to the database, and make EF Core unhappy when it tries to delete the latest migration. This should therefore be used with caution - a safer approach is to "roll forward" and create new migrations that safely undo the undesired change(s).
The template can be deployed to Azure via the Azure Developer CLI (AZD). This will setup the following:
- Azure App Services: API + MigrationService
- Azure SQL Server + Database: Data storage
- Application Insights + Log Analytics: For monitoring and logging
- Managed Identities: For secure access to Azure resources
- Azure Container Registry: For storing Docker images
-
Authenticate with Azure
azd auth login
-
Initialize AZD for the project
azd init
-
Update environment variables
azd env set ASPNETCORE_ENVIRONMENT Development
-
Deploy to Azure
azd up
Note
azd up
combines azd provision
and azd deploy
commands to create the resources and deploy the application. If running this from a CI/CD
pipeline, you can use azd provision
and azd deploy
separately in the appropriate places.
Template will be published to NuGet.org when changes are made to CleanArchitecture.nuspec
on the main
branch.
- Update the
version
attribute inCleanArchitecture.nuspec
- Merge your PR
package
GitHub Action will run and publish the new version to NuGet.org- Create a GitHub release to document the changes
Note
We are now using CalVer for versioning. The version number should be in the format YYYY.M.D
(e.g. 2024.2.12
).
If you're interested in learning more about Clean Architecture SSW offers two events:
You're interested learning more about Clean Architecture, please see this excellent video by Matt Goldman:
Alternatively, SSW has many great rules about Clean Architecture:
You can also find a collection of commumity projects built on Clean Architecture here:
Contributions, issues and feature requests are welcome! See Contributing for more information.