This template is based on Jason Taylor's Clean Architecture Template
Icon design credit goes to @antunamirna
The most simple way to obtain this template is by installing the NuGet package.
First make sure that you have the .NET 7 SDK installed on your machine.
Then run dotnet new -i CleanSolutionTemplate
to install the template.
At this moment, the supported way to create a solution using this template is from the command line. Using the template from an IDE (like Visual Studio or Rider) is not supported (you can do it but the structure will be messed up). To create a solution using this template simply run dotnet new cst -n <SolutionName>
Don't forget to change this README and LICENSE accordingly to your project's needs.
The easiest and simplest way to run a local DB is using Podman/Docker.
Run podman run --name cst-postgres -e POSTGRES_PASSWORD=password -p 5432:5432 -d postgres:15.3-alpine3.18
.
The connection string for the PostgresSQL DB in the appsettings.Development.json
will allow you to connect to the container that got created.
This template uses Codacy as the tool for code analysis and reporting on test coverage. In order to set it up follow the steps described in the docs:
- https://docs.codacy.com/getting-started/codacy-quickstart/
- https://docs.codacy.com/coverage-reporter/
- https://docs.codacy.com/repositories-configure/integrations/github-integration/#configuring
- https://docs.codacy.com/faq/general/how-do-i-block-merging-prs-using-codacy-as-a-quality-gate/
Running the coverage report locally can be done by executing the test coverage scripts inside the scripts
directory. Both are the same script, one written in Powershell and the other one in Bash. These scripts make use of the report-generator tool, please visit the ReportGenerator GitHub to know more about the project.
The project is divided as follows:
- The
scripts
directory is where all scripts should be placed. By default four come with the template to run the tests and start the containers for the tests. - The
src
directory is where all the source code should be placed. By default four projects are included here. The Api project is the default Presentation Layer, then we have the Application, Domain and Infrastructure layers. - The
tests
directory is where all the code for the tests should be placed. By default four Unit Test projects corresponding to asrc
project, an Integration Test and an End to End Test are placed here.
Note: If you want to run Docker instead of Podman for the containers, simply replace the podman
command by docker
.
This will contain all entities, enums, exceptions, interfaces, types and logic specific to the domain layer.
This layer contains all application logic. It is dependent on the domain layer, but has no dependencies on any other layer or project. This layer defines interfaces that are implemented by outside layers. For example, if the application needs to access a notification service, a new interface would be added to application and an implementation would be created within infrastructure.
This layer contains classes for accessing external resources such as file systems, web services, SMTP, and so on. These classes should be based on interfaces defined within the application layer.
This layer depends on both the Application and Infrastructure layers, however, the dependency on Infrastructure is only to support dependency injection. Therefore only ConfigureServices.cs, Configure.cs and Program.cs should be able to reference Infrastructure.
Our definition of Unit Test is a test that takes a layer in isolation and fakes everything else. We rely on DI to obtain the SUTs, the configuration for it can be found in the ServiceProviderBuilder class. These tests will run isolated from one another, making xUnit a great tool for the job. No test should depend on the execution or state of a previous test. Everything that relates to the database will be done using an InMemory Database for the Infrastructure layer and Moq for the Application layer.
Our definition of Integration Test is a test that takes the Domain, Application and Infrastructure layers and fakes only external dependencies. We rely on DI to obtain the SUTs and the configuration for it can be found in the ServiceProviderBuilder class. These tests will run sequentially, each class is allowed to keep state and rely on the state of the previous execution, making NUnit a great tool for the job. Tests within a class shouldn't depend on the execution or state of tests in different classes. Everything that relates to the database will be run within a Podman/Docker container using a real database.
Our definition of End to End Test is a test that takes all the layers and external dependencies. We do not fake. We rely on a Test Server to run our API. These tests will run sequentially, each class is allowed to keep state and rely on the state of the previous execution, making NUnit a great tool for the job. Tests within a class shouldn't depend on the execution or state of tests in different classes. Everything that relates to the database will be run against a testing/staging environment if possible or within a Podman/Docker container using a real database. Everything that relates to STS will be run against a testing/staging environment if possible or within a Podman/Docker container using a test server.
If you run into any issue or have an idea to improve the template, simply create an issue on this repo explaining what the problem/suggestion is.
This project is licensed with the MIT license.