ASP.NET Core Web API using .NET 8 and PostgreSQL with Entity Framework Core following the principles of Clean Architecture.
- π Technologies
- π οΈ Prerequisites
- π° Getting started
- ποΈ Project structure
- π Continous integration
- π Changelog manager
- βοΈ Support
- πͺͺ License
- ASP.NET Core - Cross-platform, high-performance, open-source framework for building modern, cloud-enabled, Internet-connected applications
- ASP.NET Core Identity - membership system that allows login functionality
- Entity Framework Core 7 - lightweight, extensible, open source, and cross-platform object-relational mapper (O/RM)
- AutoMapper - convention-based object-object mapper
- PostgreSQL - powerful, open-source object-relational database system
- Serilog - simple .NET logging with fully-structured events
- xUnit, FluentAssertions and Moq
- .NET 8 SDK
- PostgreSQL installed on your local machine
- Code editor (Visual Studio 2022 recommended)
The easiest way to get started is to scaffold a copy of the repository by using degit.
If you don't already have it, you can easily install it by using the following command (assuming you have Node.js installed)
npm install --global degit
Now you can download the repository without any hassle and unnecessary git history using the following command
degit https://github.com/Enterwell/dotnet-starter dotnet-starter
If you want to replace the placeholder name "Acme", you can easily do so using the script StarterRename.ps1
.\StarterRename.ps1 -newName TestApp
This will update all namespaces, usings, project names and solution file. No further action should be necessary on your part.
Set the Acme.Interface.WebAPI
as the startup project, build and run the application.
Web API is available at https://localhost:7090
and the interactive Web API Swagger documentation at the https://localhost:7090/swagger
.
By default, application will try to connect to PostgreSQL server running locally with the following configuration:
- Port:
5432
- Username:
postgres
- Password:
password
If you have your server configured differently, change the connection string in the Acme.Interface.WebAPI/appsettings.Development.json
file.
If the application was started for the first time, database needs to be initialized by executing the migrations.
- After starting the application go to the Web API Swagger documentation available at
https://localhost:7090/swagger
. - You can see two
ApplicationManagement
endpoints:/assert-migrations
- used to remotely check if the database is up-to-date with the migrations/migrate
- used to remotely run the migrations
- Execute the
/migrate
endpoint using Swagger docs - You can check if the migrations were ran by asserting once again
- After running the migrations, database is seeded with a single admin user:
- username:
admin
- email:
[email protected]
- password:
pa$$w0rd
- username:
Generate a new migration using Visual Studio Package Manager Console (from menu: Tools -> NuGet Package Manager -> Package Manager Console):
- Verify that the
Acme.Infrastructure.EF.PostgreSql
is selected as a default project
PM> Add-Migration <MIGRATION_NAME>
Core encapsulate enterprise wide business rules or, in simpler terms, core entities that are the business objects of the application. They encapsulate the most general and high-level rules. They are the least likely to change when something external changes. This contains all entities, enums, exceptions, interfaces, types and logic specific to the "domain" layer. This layer stands on its own and does not depend on any other layer or project.
Layer that encapsulates and implements all of the use cases of the system, or to put it simply, all application logic. It is dependent on the Core layer and has no dependencies on any other layer or project. This layer contains classes that are based on the interfaces defined within the Core layer.
Layer that contains classes for accessing external resources such as file systems, web services, SMTP, databases and so on. In this starter, we have Infrastructure.EF.PostgreSql
layer that contains the Entity Framework logic for accessing PostgreSQL database. It is dependent on the Core layer and has no dependencies on any other layer or project. This layer also contains classes that are based on the interfaces defined within the Core layer.
Layer that acts as a set of adapters that convert data from the format most convenient for the use case and entities to the format most convenient for some external resource like the web API or CLI. In this starter, we have Interface.WebAPI
layer that contains the logic for mapping domain logic entities into DTOs used by the controllers for providing RESTful API to the web. This layer depends on both the Application and Infrastructure layers, however, the dependency on the Infrastructure layer is here only to support dependency injection.
So, to be frank, only Program.cs is referencing Infrastructure and for that reason, we previously had a separate layer called Interface.WebAPI.Starter
that would be bootstrapping the application and its' DI container. But, to reduce the number of layers, we stopped with that practice.
We've set up a couple of basic CI pipelines for GitHub Actions. You should review them and correct your branch names, if needed.
There are actions for:
- Continous integration (CI) - checkouts, restores packages, builds, runs unit tests and adds code coverage
- Code quality analysis - runs code quality analysis using CodeQL
- Release - bumps the release version and merges changelog entries into
CHANGELOG.MD
and optionally adds the git tag (if configured)
We like to see a nice and up-to-date changelog between releases, but sometimes that's just too much work. To simplify this process, we've developed our own Changelog Manager which adheres to the Keep a changelog principles, along with a couple of integrations to help you create changelog entries:
In short, you create changelog entries either by manually adding entries (files) into the ./changes
folder (if you really want to do it that way...) or by using one of the above mentioned tools. As your PR's are merged into the stage
branch (or your equivalent development branch) this folder will accumulate entries which will be bundled up into your CHANGELOG.MD
when you create a release (ie. when you merge stage
into main
), and the folder will be purged. Rinse and repeat for your next release!
If you are having problems, please let us know by raising a new issue.
This project is licensed with the MIT License.