Clean Architecture with ASP.NET Core WebApi – Template

by

An ASP.NET Core WebAPI Solution Template that is built with Loosely-Coupled and Inverted-Dependency/Onion Architecture along with other essential integrations.

Clean Architecture with ASP.NET Core 3.1 WebApi - Swagger

Project Specifications

The Project is currently at V1 – Preview.

Here is what you can expect to get with this release.

ASP.NET Core 3.1 Web API

This is a Standalone ASP.NET Core WebAPI Solution with multiple Layers of Abstraction. The Library Projects are build on .NET Core 3.1 Libraries / .NET Standard 2.1 Libraries.

Clean Architecture

The Domain and Application Layer should be always at the Core of the Solution. This means that these layers will never depend on anything external. This makes the entire solution Clean, Testable and Scalable.

Open Source

This Project is licensed under MIT License, which means it is FREE to use , distribute. Feel free to contribute to this project as well. Let’s make this The Best Ever Template for ASP.NET Core 3.1 WebApi!

The Problem this Project Solves

Does it really make sense to Setup your ASP.NET Core Solution everytime you start a new WebApi Project ? Aren’t we wasting quite a lot of time in doing this over and over gain?

This is the exact Problem that I intend to solve with this Full-Fledged ASP.NET Core 3.1 WebApi Solution Template, that also follows various principles of Clean Architecture.

The primary goal is to create a Full-Fledged implementation, that is well documented along with the steps taken to build this Solution from Scratch. This Solution Template will also be available within Visual Studio 2019 (by installing the required Nuget Package / Extension).

  • Demonstrate Clean Monolith Architecture in ASP.NET Core 3.1
  • This is not a Proof of Concept
  • Implementation that is ready for Production
  • Integrate the most essential libraries and packages
Clean Architecture Source Code
Clean Architecture Source Code

Features

  1. Onion Architecture
  2. CQRS with MediatR Library
  3. Entity Framework Core – Code First
  4. Repository Pattern – Generic
  5. MediatR Pipeline Logging & Validation
  6. Serilog
  7. Swagger UI
  8. Response Wrappers
  9. Healthchecks **
  10. Pagination
  11. Redis Caching **
  12. In-Memory Database
  13. Microsoft Identity with JWT Authentication
  14. Role based Authorization **
  15. Identity Seeding **
  16. Database Seeding **
  17. Custom Exception Handling Middlewares
  18. API Versioning
  19. Fluent Validation
  20. Automapper
  21. SMPT / Mailkit / Sendgrid Email Service
  22. Complete User Management Module (Register / Generate Token / Forgot Password / Confirmation Mail) **

** Coming Soon

 

Onion / Hexagonal Architecture

The Onion architecture, introduced by Jeffrey Palermo, overcomes the issues of the layered architecture with great ease. With Onion Architecture, the game-changer is that the Domain Layer (Entities and Validation Rules that are common to the business case ) is at the Core of the Entire Application. This means higher flexibility and lesser coupling. In this approach, we can see that all the Layers are dependent only on the Core Layers (Application and Domain Layer is collectively called as the Core Layer).

Onion / Hexagonal Architecture

Everything done for you.

Get the Complete Source Code of this Project here. Feel free to contribute as well. The Steps to get started are mentioned in the next section.

Why Clean Architecture with ASP.NET Core WebApi?

While getting started with this Project, I could not find any Clean Architecture implementation that is specifically built for ASP.NET Core 3.1 WebAPI.

Starting with a Clean Architecture in quite Important for the lifetime of your applications. You really don’t want to re-engineer you solutions half-way down the development stages, do you?

Releases

Every Major Update will be tagged as versioned Release. Included Features and Changes will be made available within the Release Pages.

Prerequisites

  • Make sure you are running on the latest .NET Core SDK (SDK 3.1 and above only). Get the latest one here.
  • Visual Studio 2019 ( You can check out my Installation Guide of Visual Studio 2019 Community which is completely Free to use.) Make sure that ASP.NET and web development workload is installed.
  • Install the latest DOTNET & EF CLI Tools by using this command – dotnet tool install –global dotnet-ef 
  • I Recommend that you read Onion Architecture In ASP.NET Core With CQRS – Detailed article to understand this implementation much better. This project is just an Advanced Version of the mentioned article.
  • Once you clear with Onion Architecture Implementation, you will also need to be clear with CQRS MediatR Pattern. II have written step-by-step guide on how to implement CQRS using MediatR Library. Read it here.

Getting Started

To get started / check out this Boiler Plate Template for Clean Architecture with ASP.NET Core WebApi, there are quite a few ways. Let’s go through them,

1. Clone the Source Code

Navigate to the Project Repository – https://github.com/iammukeshm/CleanArchitecture.WebApi

Click on the Code -> Download ZIP, as mentioned below. This will download the entire source code for you locally to your machine (OR) Download the Latest Release from here.

Clean Architecture with ASP.NET Core WebApi

Extract the Zip file and navigate to the Root of the WebAPI Project (Not the Solution File). In this directory, open up Power Shell and run the following commands.

Before proceeding do not forget to open up the appsettings.json and change the connection strings / email settings and so on. Note that you can use separation connection strings for both Identity and Application!

dotnet restore
dotnet ef database update -Context ApplicationDbContext
dotnet ef database update -Context IdentityContext
dotnet run (OR) Run the Solution using Visual Studio 2019

When you run the application, Swagger Opens up. Here you can find the available endpoint.

2. Using the Visual Studio Project Template

Coming Soon.

Folder Structure

Here is how the Solution Folder Looks like.

clean architecture webapi folder structure

1. Core

The Core Layers will never depend on any other layer. Therefore what we do is that we create interfaces in the Application Layer and these interfaces get implemented in the external layers. This is also known and DIP or Dependency Inversion Principle.

It is also important to note that these layers are .NET Standard 2.1 Libraries. This is so because we need to make these layers as comptatible as possible with other projects. Let’s say tommorow your client wants a .NET 4.7 Solutions (quite unlikely though) with the near-same business logics. At such scenarios, .NET Standard Libraries will be of great help.

1.1 Domain

All the Entities and the most common models are available here. Note that this Layer will NEVER depend on anything else.

1.2 Application

Interfaces, CQRS Features, Exceptions, Behaviors are available here.

2. Infrastructure

Whenever there is a requirement to communicate with an external source, we implement it on the Infrastructure Layer. For example, Database or other Services will be included here. To make the separation more visible, We will maintain further sub projects with the naming convention as ‘Infrastructure.xxxxxx’ where xxxxxx is the actual Point of Concern.

2.1 Infrastructure.Identity

In this implementation, we will make use of the already AWESOME Microsoft Identity. Let’s seperate the User Managment Database from the Main Application Database. This is made possible by multiple – DbContext Classes in each of the required Infrastructure Project

2.2 Infrastructure.Persistence

An Application Specific Database will be maintained. This is to ensure that there is no relation between the DBContext classes of Application and the Identity.

2.3 Infrastructure.Shared

Now, there are some services that are common to the other Infrastructure Layers and has the possibility of use in nearly all the Infrastructure Layers. This includes Mail Service, Date Time Service and so on. Thus it is a better Idea to have a shared Infrastructure project as well.

3. WebApi

This is also known as the Presentation Layer, where you would put in the project that the user can interact with. In our case it is the WebAPI Project.

Detailed Layer-By-Layer Documentation

Coming Soon.

Support the Project

Your small contribution can help support the project and motivate me to make frequent updates to this Open Source Project. If you find this Project helpful or you learnt something from here, consider supporting.

Buy me a coffeeBuy me a coffee

Additional Resources

  • Onion Architecture In ASP.NET Core With CQRS – Detailed – We will talk about Onion Architecture In ASP.NET Core and it’s advantages. We will also together build a WebApi that follows a variant of Onion Architecture so that we get to see why it is important to implement such an architecture in your upcoming projects. 
  • CQRS with MediatR in ASP.NET Core 3.1 – Ultimate Guide – Let’s talk about CQRS in ASP.NET Core 3.1 and it’s implementation along with MediatR and Entity Framework Core – Code First Approach. I will implement this pattern on a WebApi Project. The source code of this sample is linked at the end of the post. Of the several design patterns available, CQRS is one of the most commonly used patterns that helps architect the Solution to accommodate the Onion Architecture.

Credits

There are a lot of References that I had taken in-order to build up this Solution. Few of them are Jason Taylor, Steve Smith , Nick, and many more. The eShop Repository Series of Microsoft has helped quite a lot.

14 Comments

  1. Akhil Kumar

    Many Thanks for sharing your valuable knowledge…

    Reply
  2. Arthur Kater

    Hi Mukesh,

    Nice work to put all the pieces together. Thanks!

    Question: How to get add-migration to work? I get the error message “Unable to create an object of type ‘ApplicationDbContext’. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728

    Reply
    • Mukesh Murugan

      Hi Arthur,

      First step, check what the issue is .
      add-migration Added_something -verbose

      Run this command on package manager console. It will pinpoint you to the issue. From there you can debug the issue.
      However, i think this issue is because you have not set the default project properly.
      1. Set API Project as the Staryup project.
      2. Open up package manager console.
      3. There you can see a small dropdown for default project. Choose the project where the specific context class lives.
      Run this then,

      add-migration migration_name -Context IdentityContext

      Try this and let me know.

      Thanks and regards

      Reply
      • Artyom

        Very interesting, how will you make .net standard libs to work with .net framework 4.7 if 2.1 is not supported even by .net framework 4.8…

        Reply
  3. sky

    hi mukesh,
    i really appreciate you. can you please work on multi tenant based architectures also. that would be so great. takecare

    Reply
    • Mukesh Murugan

      Hi,
      Hope you liked this implementation. Will surely work on multi-tenancy as well.
      Regards

      Reply
  4. Mark

    Can you also add a new template for ASP.Net core Web Api Including these
    Onion Architecture
    CQRS with MediatR Library
    Dapper (Instead of Entity Framework Core – Code First)
    Dommel
    Repository Pattern – Generic
    MediatR Pipeline Logging & Validation
    Serilog or Nlog
    Swagger UI
    Response Wrappers
    Healthchecks
    Pagination
    Redis Caching
    In-Memory Database
    Microsoft Identity with JWT Authentication
    Role based Authorization
    Custom Exception Handling Middlewares
    API Versioning
    Fluent Validation
    Fluent mapper
    SMPT / Mailkit / Sendgrid Email Service
    Complete User Management Module (Register / Generate Token / Forgot Password / Confirmation Mail)

    Reply
    • Mukesh Murugan

      Hi, Thanks for reaching out.

      Yes, I am already working on adding Dapper to this Solution as new Infrastructure Layer, so that you easily switch the ORM whenever you want. Just working on the architecture part.

      Dommel? Have not heard about. Will give it a look though. Will have to check out Fluent Mapper too.

      NLOG/Serilog will be integrated soon.

      Thanks,
      Hope you liked the implementation.

      Reply
      • Arun

        Thanks Mukesh ,
        I really loved the architecture that you have created.
        The only point where i am stuck is using Dapper since i also have SQL stored procedure and for me to implement SP’s are from dapper.

        Regards
        Aarun

        Reply
        • Mukesh Murugan

          Hi, Thanks for your feedback.
          You can easily add Dapper in the Infrastructure Layer, by adding a new Infrastructure Project named Infrastructure.Persistence.Dapper or something, and have your dapper implementations there. However, in the next version of this Architecture (v1.1) , I am planning to add this option as well, where users can switch between the ORM.

          Regards

          Reply
  5. Vinicius

    Hi, that is a very interesting architecture.

    Just a quick question:
    I always use the same context for the application and identity, so I can use a join when I want to get the user information that is linked in a entity.
    How would that work in this scenario? I would have to do 2 queries?

    Reply
    • Mukesh Murugan

      Hi, yes.In cases where you actually need data from the Identity table, you would have to use both these contexts in your call. I guess it is like adding a bit more security and a cleaner separation. However I am still in the process of making this architecture simple and logical to use. What are your thoughts?

      Reply
      • Vinicius

        I think this may lead to some performance issues.
        For example, if I want to get a list of products with the name of the user that created it I would have to get the list of products, and for each product do a query to get the name of the user.

        I can think of two solutions:
        – Put the ApplicationUser in the ApplicationDbContext as well, as it allows foreign keys for another schemas (at least in SQL Server)
        – Or create another user table in the ApplicationDbContext containing only the necessary information (name, email, etc) so it does not expose all the user data to the application

        Reply

Submit a Comment

Your email address will not be published. Required fields are marked *

Pin It on Pinterest