Onion Architecture In ASP.NET Core With CQRS – Detailed
In this article, We will talk about Onion Architecture In ASP.NET Core and its 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. You can find the source code of this implementation on my GitHub.
PRO TIP: This is a very detailed article covering various aspects of Onion Architecture. Do bookmark this page and continue 😀
At the end of this article, you can find a few Open Source Projects that are built using this awesome Architecture and much more!
The Need to Follow an Architecture
To maintain structural Sanity in Mid to Larger Solutions, it is always recommended to follow some kind of architecture. You must have seen most of the Open Sourced Projects having multiple layers of Projects within a complex folder structure.
Layer Vs Tiers
When there is just a logical separation in your application, we can term it as layers or N Layers. In cases where there is both a physical and logical separation of concerns, it is often referred to as n-tiered application where n is the number of separations. 3 is the most common value of N. In this article, we will deal with Layered Architecture.
This layering can help in the separation of concerns, subdividing the solution into smaller units so that each unit is responsible for a specific task and also takes advantage of abstraction. For mid to larger scaled projects where multiple teams work, layering has very obvious advantages up its sleeves. It lets a specific team or individual work on a particular layer without disturbing the integrity of the others. It makes it much easier to track changes using source control.
Also, It just makes your entire solution look clean.
Before getting into Onion Architecture in ASP.NET Core, let’s first refresh our knowledge on N Layer Architecture.
Brief Overview of N-Layer Architecture
Let’s look at one of the most popular Architecture in ASP.NET Core Applications. Here is a simple diagrammatic representation of a variation of the N-Layer Architecture. The presentation Layer usually holds the Part that the User can interact with, i.e, WebApi, MVC, Webforms, and so on. Business Logic is probably the most important part of this entire setup. It holds all the logic related to the Business requirements. Now, every application ideally has its own dedicated Database. In order to access the Database, we introduce a Data Access Layer. This layer usually holds ORMs for ASP.NET to fetch/write to the database.

Disadvantages of N-Layer Architecture
To clearly understand the advantages of Onion Architecture in ASP.NET Core Applications, we will need to study the issues with N Layer Architecture. It is one of the most commonly used Solution Architectures amongst .NET developers.
Instead of building a highly decoupled structure, we often end up with several layers that are depending on each other. This is something really bad in building scalable applications and may pose issues with the growth of the codebase. To keep it clear, in the above diagram we can see that the presentation layer depends on the logics layer, which in turn depends on the data access and so on.
Thus, we would be creating a bunch of unnecessary couplings. Is it really needed? In most cases, the UI (presentation) layer would be coupled to the Data Access Layers as well. This would defeat the purpose of having clean architecture, yeah?
In N Layer Architecture, the Database is usually the Core of the Entire Application, i.e It is the only layer that doesn’t have to depend on anything else. Any small change in the Business Logics layer or Data access layer may prove dangerous to the integrity of the entire application.
Getting Started with Onion Architecture
The Onion architecture, introduced by Jeffrey Palermo, overcomes the issues of 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.

Here is how I would break down the structure of the proposed Solution.
Domain and Application Layer will be at the center of the design. We can refer to these layers as the Core Layers. These layers will not depend on any other layers.
Domain Layer usually contains enterprise logic and entities. Application Layer would have Interfaces and types. The main difference is that The Domain Layer will have the types that are common to the entire enterprise, hence can be shared across other solutions as well. But the Application Layer has Application-specific types and interfaces. Understand?
As mentioned earlier, 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 as DIP or Dependency Inversion Principle.
For example, If your application want’s to send a mail, We define an IMailService in the Application Layer and Implement it outside the Core Layers. Using DIP, it is easily possible to switch the implementations. This helps build scalable applications.
The presentation layer is where you would Ideally want to put the Project that the User can Access. This can be a WebApi, Mvc Project, etc.
The infrastructure layer is a bit more tricky. It is where you would want to add your Infrastructure. Infrastructure can be anything. Maybe an Entity Framework Core Layer for Accessing the DB, a Layer specifically made to generate JWT Tokens for Authentication or even a Hangfire Layer. You will understand more when we start Implementing Onion Architecture in ASP.NET Core WebApi Project.
Implementing Onion Architecture in ASP.NET Core WebApi Project
To keep things simple but demonstrate the architecture to the fullest, we will build an ASP.NET Core Web API that is quite scalable. For this article, Let’s have a WebApi that has just one entity, Product. We will perform CRUD Operations on it while using the Onion architecture. This will give you quite a clear picture.
Here is a list of features and tech we will be using for this setup.
- Onion Architecture
- Entity Framework Core
- .NET Core 3.1 Library / .NET Standard 2.1 Library / ASP.NET Core 3.1 WebApi
- Swagger
- CQRS / Mediator Pattern using MediatR Library
- Wrapper Class for Responses
- CRUD Operations
- Inverted Dependencies
- API Versioning
Setting up the Solution Structure
We will start off by creating a Blank Solution on Visual Studio. PS, I use Visual Studio 2019 Comunity which is completely FREE. To install this IDE, check my article here.

Let’s give it a proper Name.

Under the Blank Solution, add 3 new folders.
- Core – will contain the Domain and Application layer Projects
- Infrastructure – will include any projects related to the Infrastructure of the ASP.NET Core 3.1 Web API (Authentication, Persistence, etc)
- Presentation – The Projects that are linked to the UI or API. In our case, this folder will hold the API Project.

Let’s start adding the required projects. Firstly, under the Core Folder Add a new .NET Standard Library and name it Domain.
Why .NET Standard? We know that Domain and Application Project does not depend on any other layers. Also the fact that these projects can be shared with other solutions if needed (Maybe another solution that is not .NET Core, but .NET Framework 4.7). Get the point?

A wise person once said – ” Delete the Default Class1 Created by Visual Studio. Always Delete them. “
After creating the Domain project, right-click on properties and change the target framework to .NET Standard 2.1 (which is the latest .NET Standard version at the time of writing this article.)

Similarly, create another .NET Standard Library Project in the Core Folder. Name it Application. Do not forget to change the target version here as well.
Next, let’s go to the Infrastructure Folder and add a layer for Database, (EFCore). This is going to be a .NET Core Library Project. We will name it Persistence.

Finally, in the Presentation layer, add a new ASP.NET Core 3.1 WebApi Project and name it WebApi.

This is what we will be having right now. You can see the clear separation of concerns as we have read earlier. Let’s start building up the architecture now.

Adding Swagger To WebApi Project
Tip #1 – Always use Swagger while working with web APIs. It is so much helpful to have it.
Install the following packages to the WebApi Project via Package Manager Console
Install-Package Swashbuckle.AspNetCore Install-Package Swashbuckle.AspNetCore.Swagger
We will have to register Swager within the application service container. Navigate to ../Startup.cs and add these lines to the ConfigureServices method.
#region Swagger services.AddSwaggerGen(c => { c.IncludeXmlComments(string.Format(@"{0}\OnionArchitecture.xml", System.AppDomain.CurrentDomain.BaseDirectory)); c.SwaggerDoc("v1", new OpenApiInfo { Version = "v1", Title = "OnionArchitecture", }); }); #endregion
Then, add these lines to the Configure method.
#region Swagger // Enable middleware to serve generated Swagger as a JSON endpoint. app.UseSwagger(); // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), // specifying the Swagger JSON endpoint. app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "OnionArchitecture"); }); #endregion
Next, we will need to add the XML File (For Swagger Documentation). To do this, right-click the WebApi Project and go to properties. In the Build Tab enable the XML Documentation file and give an appropriate file name and location. I have added the XML file to the root of the API Project.

Make sure that the WebApi Project is selected as the Startup Project. Now Build / Run the Application and navigate to ../swagger. We have got swagger up and running.

Tip #2 – While running the application, you would see that it navigated to ../weatherforecast by default. This is because of launchSettings.json settings. In the WebApi Project, Properties drill down, you can find a launchsettings.json file. This file holds all the configurations required for the app launch. Change the launch URL to swagger. Thus, the swagger will open up by default every time you run the application. This helps you save some time.

Adding The Entities to the Domain Project
Now, let’s work on the Core Layers starting from the Domain Project. So what is the function of the Domain Layer? It basically has the models/entities, Exception, validation rules, Settings, and anything that is quite common throughout the solution.
Let’s start by adding a BaseEntity class at Common/BaseEntity.cs in the Domain Project. This abstract class will be used as a base class for our entities.
public abstract class BaseEntity { public int Id { get; set; } }
Now add a Product Class that inherits the Id from the BaseEntity. Create a new class Entities/Product.cs in the Domain Project.
public class Product : BaseEntity { public string Name { get; set; } public string Barcode { get; set; } public string Description { get; set; } public decimal Rate { get; set; } }
Adding the Required Interfaces And Packages in Application Layer
As mentioned earlier, the Application Layer will contain the Interfaces and Types that are specific to this Application.
Firstly, Add Reference to the Domain Project.
Then, install the required packages via Console.
Install-Package MediatR.Extensions.Microsoft.DependencyInjection Install-Package Microsoft.EntityFrameworkCore
We have an Entity named Product. Now we need to establish this class as a Table using Entity Framework Core. So we will need an ApplicationDBContext. But the catch is that we won’t create the actual concrete implementation of the ApplicationDbContext here in the Application Layer. Rather, we will just add an IApplicatoinDbContext Interface so that the EF Logics does not fall under the Application Layer, but goes to the Persistence layer which is outside the core,
This is how you can invert the dependencies to build scalable applications. Now, the advantage is that tomorrow, you need a different implementation of the ApplicationDbContext, you don’t need to touch the existing code base, but just add another Infrastructure layer for this purpose and implement the IApplicationDbContext. As simple as that.
Create a new folder Interfaces in the Application Project. Add a new interface in it, IApplicationDbContext
public interface IApplicationDbContext { DbSet<Product> Products { get; set; } Task<int> SaveChanges(); }
This is another variant that I have noticed in many huge solutions. Let’s say you have around 100 interfaces and 100 implementations. Do you add all these 100 lines of code to the Startup.cs to register them in the container? That would be insane from the maintainability point of view. To keep things clean, what we can do is, Create a DependencyInjection static Class for every layer of the solution and only add the corresponding. required services to the corresponding Class.
In this way, we are decentralizing the code lines and keeping our Startup class neat and tidy. Here is an extension method over the IServiceCollection.
public static class DependencyInjection { public static void AddApplication(this IServiceCollection services) { services.AddMediatR(Assembly.GetExecutingAssembly()); } }
Here we will just Add Mediator to the service collection. We will implement the Mediator pattern later in this tutorial.
And all you have to do in WebApi’s Startup class is just add one line. This essentially registers all the services associated with the Application Layer into the container. Quite handy, yeah?
services.AddApplication();
Implementing MediatR for CRUD Operations
In the Application Layer, Create a New Folder called Features. This will have all the logic related to each Feature / Entity. Under this folder, add a new one and name it ProductFeatures. Then add a Commands and Queries folder to it.
I have already written a detailed article on MediatR and CQRS patterns in ASP.NET Core 3.1 WebApi Project. You can follow that article and add the Required Commands and Handlers to the Application Layer.

I will add the links to the source code of each file. Basically, these 5 Classes would cover our CRUD Operations implementation. Make sure that you have gone through my article about CQRS for ASP.NET Core before proceeding.
- CreateCommand – https://github.com/iammukeshm/OnionArchitecture/blob/master/Application/Features/ProductFeatures/Commands/CreateProductCommand.cs
- DeleteCommand – https://github.com/iammukeshm/OnionArchitecture/blob/master/Application/Features/ProductFeatures/Commands/DeleteProductByIdCommand.cs
- UpdateCommand – https://github.com/iammukeshm/OnionArchitecture/blob/master/Application/Features/ProductFeatures/Commands/UpdateProductCommand.cs
- GetAllQuery – https://github.com/iammukeshm/OnionArchitecture/blob/master/Application/Features/ProductFeatures/Queries/GetAllProductsQuery.cs
- GetByIdQuery – https://github.com/iammukeshm/OnionArchitecture/blob/master/Application/Features/ProductFeatures/Queries/GetProductByIdQuery.cs
Setting Up EF Core on the Persistence Project
Firstly, add a connection string to the appsettings.json found in the WebApi Project.
"ConnectionStrings": { "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=onionDb;Trusted_Connection=True;MultipleActiveResultSets=true" }
With the CRUD logic out of the way, let’s set up EFCore in the Persistence Layer and try to generate a database. Install the following packages to the Persistence Project.
Install-Package Microsoft.EntityFrameworkCore Install-Package Microsoft.EntityFrameworkCore.SqlServer
Remember we created an IApplicationDBContext Interface in the Application Layer? This is where we will be implementing it. Create a new folder named Context and add a new class ApplicationDbContext. This class will implement IApplicationDBContext.
public class ApplicationDbContext : DbContext, IApplicationDbContext { public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { } public DbSet<Product> Products { get; set; } public async Task<int> SaveChanges() { return await base.SaveChangesAsync(); } }
We will have to register IApplicationDBContext and bind it to ApplicationDbContext, right? Similar to the Application layer, we will have to create a new class just to register the dependencies and services of this layer to the service container.
Add a new static class, DependencyInjection
public static class DependencyInjection { public static void AddPersistence(this IServiceCollection services, IConfiguration configuration) { services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer( configuration.GetConnectionString("DefaultConnection"), b => b.MigrationsAssembly(typeof(ApplicationDbContext).Assembly.FullName))); services.AddScoped<IApplicationDbContext>(provider => provider.GetService<ApplicationDbContext>()); } }
And in the Startup class/ ConfigureServices method of the WebApi Just Add the following line. You can now see the advantage of this kind of approach.
services.AddPersistence(Configuration);
Generate the Migrations and the Database
As our ApplicationDbContext is configured, let’s generate the migrations and ultimately create a Database using Ef Core Tools – Code First Approach.
Install the following packages in the WebApi Project.
Install-Package Microsoft.EntityFrameworkCore.Tools Install-Package Microsoft.EntityFrameworkCore.Design
Now, open up the package manager console and select the Persistence project as the default project (as mentioned in the screenshot below.). This is because the actual ApplicationDBContext is implemented in the Persistence layer, remember?
Then, run the following commands to add migrations and to generate/update the database.
add-migration Initial update-database

You will get a ‘Done’ message.
Adding API Versioning
Just to make our solution a bit clean, let’s also add API Versioning to the WebAPI.
I have written a detailed article on API Versioning in ASP.NET Core 3.1 WebApi. Feel feel to read it to get a complete idea of this concept.
Install the required package.
Install-Package Microsoft.AspNetCore.Mvc.Versioning
In the Startup/ConfigureServices of the API project, add these lines to register the Versioning.
#region API Versioning // Add API Versioning to the Project services.AddApiVersioning(config => { // Specify the default API Version as 1.0 config.DefaultApiVersion = new ApiVersion(1, 0); // If the client hasn't specified the API version in the request, use the default API version number config.AssumeDefaultVersionWhenUnspecified = true; // Advertise the API versions supported for the particular endpoint config.ReportApiVersions = true; }); #endregion
Setting up the Controllers
This is the final step of setting up Onion Architecture In ASP.NET Core. We will have to wire up a controller to the Application Layer.
Create a Base Api Controller. This will be an Empty API Controller which will have API Versioning enabled in the Attribute and also a MediatR object. What is the aim of this Base Controller? It is just to reduce the lines of code. Say, we add a new controller. We will not have to re-define the API Versioning route or the Mediator object. But we will just add the BaseAPI Controller as the base class. Get it? I will show it in implementation.
Add a new Empty API Controller in the Controllers folder and name it BaseApiController.
using MediatR; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; namespace WebApi.Controllers { [ApiController] [Route("api/v{version:apiVersion}/[controller]")] public abstract class BaseApiController : ControllerBase { private IMediator _mediator; protected IMediator Mediator => _mediator ??= HttpContext.RequestServices.GetService<IMediator>(); } }
You can see that we are adding the API Versioning data to the route attribute and also creating an IMediator object.
Next, let’s create our actual ENtity endpoint. Create a new folder inside the Controllers folder and name it ‘v1’. This means that this folder will contain all the Version 1 API Controllers. Read more about API Versioning to understand the need for this here.
Inside the v1 Folder, add a new empty API Controller named ProductController. Since this is a very basic controller that calls the mediator object, I will not go in deep. However, I have previously written a detailed article on CQRS implementation in ASP.NET Core 3.1 API. You could go through that article which covers the same scenario. Read it here.
[ApiVersion("1.0")] public class ProductController : BaseApiController { /// <summary> /// Creates a New Product. /// </summary> /// <param name="command"></param> /// <returns></returns> [HttpPost] public async Task<IActionResult> Create(CreateProductCommand command) { return Ok(await Mediator.Send(command)); } /// <summary> /// Gets all Products. /// </summary> /// <returns></returns> [HttpGet] public async Task<IActionResult> GetAll() { return Ok(await Mediator.Send(new GetAllProductsQuery())); } /// <summary> /// Gets Product Entity by Id. /// </summary> /// <param name="id"></param> /// <returns></returns> [HttpGet("{id}")] public async Task<IActionResult> GetById(int id) { return Ok(await Mediator.Send(new GetProductByIdQuery { Id = id })); } /// <summary> /// Deletes Product Entity based on Id. /// </summary> /// <param name="id"></param> /// <returns></returns> [HttpDelete("{id}")] public async Task<IActionResult> Delete(int id) { return Ok(await Mediator.Send(new DeleteProductByIdCommand { Id = id })); } /// <summary> /// Updates the Product Entity based on Id. /// </summary> /// <param name="id"></param> /// <param name="command"></param> /// <returns></returns> [HttpPut("[action]")] public async Task<IActionResult> Update(int id, UpdateProductCommand command) { if (id != command.Id) { return BadRequest(); } return Ok(await Mediator.Send(command)); } }
That’s quite everything in this simple yet powerful implementation of Onion Architecture in ASP.NET Core. Build the application and let’s test it.
Since we are already talking about a form of Clean Architecture in ASP.NET Core Applications, it would help if you read about certain tips to write clean and scalable C# Code. This knowledge will drastically improve the way you start building applications in .NET – Read the article here (20 Tips to write Clean C# Code)
Testing
Run the application and open up Swagger. We will do a simple test to ensure that our solution works. I will just create a new product and make a request to query all the existing products as well.


You can see that we receive the expected data.
Advantages of Onion Architecture in ASP.NET Core
The advantages of this design are as follows.
Highly Testable – Since the Core has no dependencies on anything else, writing automated tests are flexible,
Database Independent – Since we have a clean separation of data access, it is quite easy to switch between different database providers.
Switchable UI Layer (Presentation) – Since we are keeping all the crucial logic away from the presentation layer, it is quite easy to switch to another tech – including Blazor.
Much Cleaner Codebase with well-structured Projects for better understanding with teams.
Further Improvements
Since this is a very standard implementation of Onion Architecture in ASP.NET Core to make it clear for you guys, I have avoided several components like Authentication, Exception Handling, Mediator Pipeline Logging, Error Logging, Background Processing, Response Wrappers to keep the size of the article compact.
However, I have covered a few of these topics in other articles in my blog already. You could go through them to understand the core concepts and to learn how everything works.
- Pagination & Response Wrappers
- JWT Authentication in API – With Refresh Tokens.
- Error Logging with Serilog
- Background Job Processing with Hangfire
I am planning to build a fully-fledged Clean Architecture Solution Template, which you guys can just download and start using for your new projects in no time. I would like to know your opinion about this. A Standalone WebApi Clean Architecture Solution? MVC Clean Architecture Solution? Let me know in the comments section below.
Introducing fullstackhero – .NET 6 WebAPI Boilerplate
Here is a Full-Fledged Web API Clean Architecture Solution for .NET 6.0 – Open Source – Free for the community. Let’s build the perfect Starter Template for anyone who gets started with Clean WebApi Projects!
fullstackhero’s .NET Web API Boilerplate is a starting point for your next .NET 6 Clean Architecture Project
that incorporates the most essential packages and features your projects will ever need including out-of-the-box Multi-Tenancy support. This project can save well over 200+ hours
of development time for your team.
Learn more about the project here – READ

Blazor Fan? Here is something for you!

Introducing Blazor Hero!
Blazor Hero – A Clean Architecture Template built for Blazor WebAssembly using MudBlazor Components. It’s as easy as running a line of CLI command to start generating awesome Blazor Projects!
support me
Thank you for visiting. If you like my content and code, support me by buying a couple of coffees so that I can find enough time to research & write new articles. Cheers!
Summary
Fun Fact – Microsoft themselves recommend this kind of architecture for complex solutions. Few of the solutions developed and maintained by Microsoft MVPs like eShopOnWeb and eShopOnContainers also follow a similar (slightly more complicated variant of this approach).
I hope that this is quite understandable to all, especially the ones starting about with the entire Solution Architecturing Stuff. Let me know your feedback and the scopes of improvement in this approach. You can find the entire source code on my Github Repository. Feel free to fork it and make necessary contributions if you feel so 😀 Happy Coding 🙂
As promised, you have delivered again Mukesh. Still not completely clear about what goes where but your article has greatly improved my understanding about this architecture. I also liked that you started with a clean slate as most out there just show it ready-made and try to explain from there. I am leaning towards the API template as I usually use SPA’s. Overall, awesome stuff.
Hi Victor, Thanks for the early feedback. Yes, this is quite a lot of details that may be overwhelming initially. I have tried to make it as simple as possible to understand how the entire architecture is designed. But I guess there is a lot of room for optimizing the content. I Will work on that as well. However, you could also check the code on my GitHub to get a detailed understanding.
Thanks and Regards
This post is very clear and easy to understand.
And I am accidently know your website from the Asp.Net Core on Facebook several months ago and still follow you until now.
You has helped me a lots to improve my Asp.Net skills! I have read a lot of websites on the internet but almost these a articles are not clearly or hard to understand because they don’t write everything from scrath like you did!
Keep posting!
Thanks you so much Mukesh!
Hi. Thanks for your lovely feedback. Hoping to bring in more rich articles.
Thanks and Regards.
Your contacts are amazing. Is So clean and professional. Thank you
Like with many online examples, your example is missing real life examples. It would been even better when you implement validation rules, authentication/authorization, etc.
This way developers can really learn how the onion architecture is implemented.
Anyway thanks for effort, really appreciated.
YES! What Rob says. There are so many unanswered questions and pitfalls once you start coding. For beginners it would be extremely beneficial to have real world examples
https://github.com/gothinkster/aspnetcore-realworld-example-app – this might help you
What a pleasure to follow an article with code that works straight away. Now I want to read your other articles as well!
Hi Arthur, Thanks for the feedback.
I have covered many aspects of ASP.NET Core. Please go through the article list.
Thanks and regards
Thala it’s awesome… Keep posting ?
Thanks for the feedback Arjunan 😀
Good article for Beginners. Keep doing it. All the best.
Thanks Jeeva
Nice article, i am writing a guide on how we can use the language-ext functional library in C# with the onion architecture as seen in the sample application
https://github.com/louthy/language-ext/tree/main/Samples/Contoso
the book is almost done
https://leanpub.com/practical-functional-CSharp
i will send you a copy when i finish it.
Hi. That’s a pretty nice topic. Would love to read to your book.
Thanks & Regards.
services.AddPersistence(Configuration);
not working for me, do I need to add project reference to webapi?
If yes, then whats the point of abstraction.
Yes, I think that’s wrong, by theory it should be inside application DI container
Oops sorry, that’s right you have to add Infrastructure to your WebApi
yes started with very good notion but ending up few things which is not really great and can be modified in next version of this boilerplate code
* Avoid direct reference of DAL/Persistence layer to Presentation layer
* can introduce AggregateRoot etc
* we can also avoid having reference of EF in application and Presentation layer
Well the notion is Data access layer technology keep changing after almost 3-4 years of life span.
So if tomorrow we want to change EF with any other ORM(like dapper etc) it will impact Persistence, Application and Presentation layer. which is NOT good.
since we are ending up with CQRS then we may think of adding event-sourcing etc, however event sourcing or event storing is NOT compulsion to to implement CQRS
Thanks Mukesh for your effort in this great article but when will you write about these topics ‘Authentication, Exception Handling, Mediator Pipeline Logging, Error Logging, Background Processing, Response Wrappers’
Hi, Thanks for writing.
Authentication, Response Wrappers, Error Logging and Job Processing is already covered in my other articles.
Here are the links –
https://codewithmukesh.com/blog/aspnet-core-api-with-jwt-authentication/ (Auth)
https://codewithmukesh.com/blog/hangfire-in-aspnet-core-3-1/ (job processing)
https://codewithmukesh.com/blog/serilog-in-aspnet-core-3-1/ (error logging)
https://codewithmukesh.com/blog/pagination-in-aspnet-core-webapi/ (wrappers & paginations)
I forgot to add the links to this articles. Thanks for reminding me 😀
Regards.
Firstly, Add Reference to the “Domain” Project.
Then, install the required packages via Console.
Install-Package MediatR.Extensions.Microsoft.DependencyInjection
Install-Package Microsoft.EntityFrameworkCore
—————————————————————————————————-
I think it should be in Application Project, shouldn’t it?
I’ve been building an application with similar architecture. There should be no reference from Presentation layer to the Infrastructure layer, where the ApplicationDbContext is. But I have not been able to achieve this in practice. You run database migrations directly with command update-database from Package Manager Console. But what about in production? I want to have automatic migrations there when I deploy new version. Natural place would be to run migrations in Startup class (which is in Presentation layer because it’s application root). I’ve registered my dependency in Infrastrucure layer as you by using IApplicationDbContext interface (I use Autofac modules but same idea), but when I execute the Migrate method in startup, I get following error:
Unable to create an object of type ‘ApplicationDbContext’. Add an implementation of ‘IDesignTimeDbContextFactory’ to the project, or see https://go.microsoft.com/fwlink/?linkid=851728 for additional patterns supported at design time.
The only way around seems that I need to implement IDesignTimeDbContextFactory interface in Presentation layer, and then I’m forced to have reference to Infrastrucure layer, like this: https://codingblast.com/entityframework-core-idesigntimedbcontextfactory/
Any advice? How you handle migrations in production?
Given the fact that ASP.NET Core has DI and Services, it would not make sense to not have a reference between these layers.
Running migrations / seeding at startup might be a bit of performance bottleneck. You could use the CLI for this. Sometimes we use SQL scripts as well when required. (There is something called Script migrations in EFCore).
Thanks and Regards
Database migration should be handled by your CI/CD pipeline. Your application code shouldn’t know nor care about such thing as the database schema version.
This is a infrastructure concern and should be handled by the application infrastructure. It can be a separate repo that creates external resources (a database is the simplest example) or a tool that lives in the application’s repo but runs before the application itself.
This way you achieve one of the most important principles: the separation of the application and infrastructure layers. Which allows while coexist also be developed by separate people and at separate pace.
Thanks for the article.
Even though you said application layer doesn’t depend on any other layers, you immediately leak entity Framework and asp.net core into it by the means of dbset and iservicecollection. This is effectively the same as leaking infrastructure and presentation layer into application layer, you’re bound to the technologies and cannot replace them with anything else.
Hi, Thanks for writing.
Yes, EFCore is installed in the Application layer as well. This approach is under the assumption that we would not switch away from EFCore for a very long time, which I think would not happen for at least the next 10-15 years. Also, Application layer is not depending on anything else other than the domain entities.
Application is the composition root so must know (references) all underlying libraries and explicit dependencies. You may have some implicit but then the app/cr have no knowledge of them.
You can move the composition logic in a separate project but in most cases it makes no difference, nor sense.
Adding a layer of abstraction for ORM or cloud provider are the best example of faux abstraction, the one that add no good but unnecessarily complicates the codebase. it’s also known as the overengineering. There are special cases when you need (a library to do exactly that) but again in most cases it makes no sense.
You may want to sort usings in a way that System will go on top. You can configure VS accordingly.
Also validation clutters the code of controllers, should be moved to a separate class (because of OOP+SRP which are the foundational principles behind CQRS).
Yes, Fluent Validations are great for this purpose.
Hi, Thanks for the article and you are doing great effort, please keep it up.
In Persistence layer SaveChanges() should not be override method?
Hi, Thanks!
SaveChanges depends on you actually. This is just a demonstration. You could use SaveChangesAsync as well, to keep the existing savechange();
Hi Mukesh, thank you for this great article.
I am reading this on an Ipad pro (1024×1366) and there is a horizontal scrollbar that is a bit annoying when I scroll vertically.
Issue seems like the deeply nested comments.
Hope you can take a look at it.
Hi, Thanks for the feedback.
I am sorry for the experience. Will give it a look. Thanks for letting me know.
Regards.
I had been working on a similar .NET Core onion architecture example for my team as well, so I’ve forwarded this article to them while I finish up my own example. I anticipate the setup walkthrough being more helpful than my sequence of PRs they would be viewing. Thanks for the writeup!
I forwarded the article with the following caveats though…
– Anemic domain models are an anti-pattern (https://martinfowler.com/bliki/AnemicDomainModel.html). The Product class, being part of the Domain project, falls squarely in this category. Primitive obsession is also a problem (see https://blog.ploeh.dk/2011/05/25/DesignSmellPrimitiveObsession/). The Product class is being used for both in-memory processing and for persistence, a clear violation of the single responsibility principle. Pluralsight has a great course on moving off the anti-pattern: https://www.pluralsight.com/courses/refactoring-anemic-domain-model
– As someone else already mentioned, the IApplicationDbContext interface couples consuming components to the use of EF Core (because DbSet is a public property field). Introducing DDD repositories that hide EF Core entirely would be preferred. https://docs.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/infrastructure-persistence-layer-design has more details.
– Since MediatR is already being used to encapsulate system commands, one could instead implement the “unit of work” pattern as a generic pipeline behavior rather than requiring developers to inject IApplicationDbContext and call SaveChanges explicitly for every request handler. https://github.com/kgrzybek/modular-monolith-with-ddd#36-cross-cutting-concerns has some relevant details (in addition to being a high-quality comprehensive .NET Core onion/CQRS/DDD example).
Again, I appreciate the writeup! It just has a few less-than-ideal architecture choices (for long-lived solutions) that prevent me from recommending it as-is. I’m happy to answer any questions.
Hi. Thanks for the feedback. Firstly, this is just a basic level implementation for the beginners. Did not want it to be much complex.
1. Yes, Automapper and DTO classes will be used.
2. Isnt Repositories a bad idea to go along with EFCore? and more redundant code?
Thanks for sharing, and I am currently working on a full fledged Clean Architecture for WebApi.
Regards
Could you give an example of why you might think repositories are a bad idea alongside EF Core and why they would introduce redundant code?
https://docs.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/infrastructure-persistence-layer-implemenation-entity-framework-core has some information about this… Is there anything in that document related to your concern?
Given the fact that EFCORE is already built on Repository pattern and UOW, do you really need another layer of abstraction layer over it using a IREPO? I really don’t see any advantage of such an approach here. Also, as the application scales up, doesn’t your repo count grow too unnecessarily? Please correct me if I am wrong
The answer is, as always, “it depends”, but I would argue the extra abstraction layer is definitely worth the effort for projects of sufficient size and scope.
As currently written, your request handler implementations depend on **the entire database**. That is what IApplicationDbContext is; presumably, you will be exposing all tables with this object. For a simple project, this may be fine. However, as your project increases in size and scope, that particular architecture choice will enable database-level entanglements that make it incredibly difficult to refactor and decompose the solution (into modules and/or microservices) down the road. I recommend the book Monolith to Microservices by Sam Newman for some insights on this topic.
“The entire database” is not an abstraction. It’s too low-level. Interestingly, per your own admission, “EFCORE is already built on Repository pattern and UOW” and so why have IApplicationDbContext at all if all it does is expose EFCore classes (DbSet) and functions? YAGNI.
Implementing your own repositories (one per aggregate root) as an abstraction layer over top of EF Core has multiple benefits:
– your domain layer can define the repository interface, while the implementation of the repository goes in the infrastructure layer; this is onion architecture in action! (depend on abstractions, not implementations)
– per DDD, request handlers are analogous to system commands, and system commands are part of your domain layer; your current implementation violates DDD onion architecture because your request handlers depend directly on EFCore (via IApplicationDbContext)
– repositories expose the precise, limited set of database operations required to service your domain; this makes your code **simpler** because you have defined your own API over the raw database and your request handlers will use this API
– per the previous point, database-related complexity is confined to the repositories: the repository takes care of loading and mapping everything needed to construct the aggregate root in memory; with your current implementation, this complexity will go in your request handlers, which should be concerned with domain logic only
– per the previous two points, repositories are useful and reusable (they bundle reusable pieces of database functionality)
Elsewhere you had mentioned that adding repositories increases lines of code and yes, it does; however, “number of lines of code” is useless as a quality metric. Coupling between components and between layers is a much better quality heuristic, and onion architecture is all about managing that coupling.
Great. This actually cleared a lot of Architecture doubts for me. Thanks! So, in the implementation of the Repository, is it better to use the concrete class ApplicationDbContext? or go with IApplicationDbContext? So with this approach, we no longer are bound to just EFCore. Else, is there any major issue that you see with this implementation. PS, apart from the usage of Automapper / DTO Classes
Thanks and Regards
It is fine for the repository implementations to be directly coupled to EFCore (i.e. use ApplicationDbContext directly). While the repository **abstraction** is part of your domain layer, the **implementation** of the repository abstraction is an infrastructure concern and resides on the outermost layer of the onion. Your application’s composition root (which has knowledge of all components used in your system) is responsible for associating that repository abstraction with its implementation. Your request handlers will not know about the implementation of the repository at all (provided your repository abstraction does not leak implementation details).
You can find an example of this at https://github.com/kgrzybek/modular-monolith-with-ddd/blob/master/src/Modules/Meetings/Domain/Meetings/IMeetingGroupRepository.cs (abstraction in domain layer) and https://github.com/kgrzybek/modular-monolith-with-ddd/blob/master/src/Modules/Meetings/Infrastructure/Domain/Meetings/MeetingRepository.cs (implementation in infrastructure layer). I highly encourage you to check out that GitHub repo for more high-quality examples of DDD onion architecture in action. It certainly upped my game!
There is no essential difference between n-tier, onion, hexagonal, layered etc architectures. If you were to cut from the outside to the centre of your onion diagram, then bend the edges upwards, you’d have the same diagram as for n-tier, for example.
You mention that n-tier layers are tightly coupled, but that is not actually a requirement! They may be, but that’s just poor design. It remains poor design no matter which architecture you think you’re using. It is equally possible to do “onion architecture” badly and tightly couple everything.
These days we have a different idea of what should go in a layer than 30 years ago, and we are more careful about where we put domain logic, presentation logic, and so on. But the architectural principles are all essentially the same.
Layers should not depend too tightly on each other (and should only have any dependency one way, and one layer deep). But that always applies.
The details always matter here. All these architectures are basically saying you should split up your code into separate areas of concern, and all the normal rules about dependencies and coupling always apply, redardless. If you put your code in the wrong layer, or couple things that shouldn’t be coupled, or whatever, none of the architectures will be successful.
Moreover, I think you have made several mistakes in your example.
Using solution folders in Visual Studio is bad. They are are horrible mistake made by Microsoft, and should never be used.
Using different projects for different layers is only ever coincidentally a good idea. You’d have to have a very large project before doing that made any sense, in which case moving the application into a more service-based architecture might well be a better choice.
You should use different projects when you need different deliverables. Layers do not necessarily need to be in different projects, especially in small applications.
And it is still extremely disappointing that people refuse to work in a test-driven way, and examples like this ignore testing altogether.
Hi Mukesh,
This is a very nice introductory article to some important concepts, and you deserve props for contributing to the community.
However, I wanted to correct a terminology issue. It’s relatively minor, but could lead to confusion for some people down the road.
You are using CQS (Command Query Seperation), not CQRS (Command Query Responsibility Segregation).
Command Query Seperation splits commands and queries into different request types, where commands alter state and may introduce side effects, while queries are read-only and side-effect free. The two types of requests can/do share a common model and data store. This is an application level pattern to clarify intent.
Command Query Responsibility Segregation is the use of two completely separate models, and often different data stores, where the query store is generally optimized for read efficiency, while the command store is optimized for processing changes. For instance, your Commands may use a service bus or Event Sourcing to send changes on for further processing, while your Queries may use compiled SQL views for querying.
CQS also tends to imply immediate consistency between the read and write models, while CQRS often implies eventual consistency between the read and write models.
Anyway, I suspect you know much or all of this, but I thought it worth addressing so nobody gets confused.
Thanks again
Hi. Nice and clean article. I have one question though: are you using the IDbContext for a specific reason? Do you prefer this instead of the Repository pattern? Normally I use repositories because I can work without any EF reference in my domain / application layer but having a DbContext can be handy when using things like .Include(). Just wondering 🙂
Thanks for your feedback!
This is quite a debated question over at the community. This is how I look at it. EFCore is a well-matured variant of EF. EFCore implements Repository Pattern and UOW already, as stated by Microsoft. In most of the cases, I fail to see the advantage of having another repository layer over it. Get it? Why have another abstraction of Repository, when it is already done within EFCore? Also, with this approach, doesn’t the Lines of code increase? I may be wrong but haven’t come across a use-case where I really need a repo class. What do you think about this?
Good point. Maybe I try to hard not to get any implementation details in the Application/Domain layer. It makes it harder in some cases. I have swapped EF Core for Dapper (but only once) which was fairly easy because of the repos though. Gonna think about it, thanks!
Hi ,
Thanks for the perfect explanation. I just’ve a question , In case of integrating with other component , let’s say twilio service , so in this case I should Add the interfaces with the desired twilio functionality i want to use, in the application layer then create new project under infrastructure folder ex: XYZ.Infrastructure.Twilio then add the implementation there , correct me if I’m wrong 🙂
Hi, Thanks for the Feedback.
Yes. It actually depends on the use case as well.
1. You could either merge services like Twilio into a single Project layer and implement the interface within each corresponding folder. eg. Infrastruction.Communication / Twilio. This is if you think the infrastructure implementation is not very complex.
2. In other cases, like you have mentioned, go with Infrastructure.Twilio. This is if you want a really good separation of the implementations, as each Project will be generating a DLL.
Thanks and Regards.
While this architecture is clean enough and as Mukesh said , EFCore already implements Repository Pattern , but still there is some cases you can introduce new Repository layer ,
1- If you want to hide the implementation of your ORM ( EF ) and you have some assumtions that you would change your ORM later ( which is not the case most of the time)
2-if you want to limit access to some of your entities you can Introduce a new empty inteface called IAggregateroot then make your IRepository inherit from IAggregateRoot then set your entites which is accessable every where to implement IAggregateRoot except the one you don’t want anyone to access it directlty so in this case when you try to inject IRepository where T : IAggregateRoot it will work only with the accessable entities , ex : you have order & orderItem and you only restrict access to order entites and any change to orderItem can be done through order 🙂
Hi Mukesh
Thanks for this great article,I am agree that you are saying you are going to build boilerplate that any one can download and can start working.
Just some question in my mind,thought you can give clear answer on them,because i was working on CQRS but the project was microservice and is very big.
So can we use CQRS with small projects or it can work good with only big one.
Hi Mohsin, Thanks for the feedback.
CQRS is something that makes you controllers THIN. It is always a good practise to follow a well-defined architecture for every solution. CQRS with MediatR has quite a lot of advantages like the Pipeline Behaviours and Logging. Answering to your question, It completely depends upon you. If the projects are too small and there is no scope of scalability in the game, you would not even ideally need an architecture. But if there is a chance of requirement changes and additional features / infrastructure, it’s better to use CQRS for future proofing you applications. Also, CQRS makes your application much more readable and maintainable. What do you think about this?
From my experience, once you start getting comfortable with CQRS, it’s really tough to avoid using it 😀
Thanks and Regards
Hello,
Thanks for this great article. I suppose I can’t use UnitOfWork pattern and generic repo even with Onion architecture. Could you confirm (or not)
thanks,
Hi, Thanks for the feedback!
Yes, you can definitely use Repository Pattern alongside Onion Architecture. It gives a better separation between your actual database of choice and your data access code. It depends on how organized you want your project to be and how comfortable you are with the patterns.
Thanks and Regrds
Sorry I wanted to say “can” and not “can’t”
Thanks for this article. I am relatively new to building large programs, I am only 17 years old. For a long time I was looking for material where it will be possible to learn trending technologies in building web applications, and your article is the beginning for me. Thanks again
Good job Mukesh!
Do you have in mind publish another release of the Full Fledged Clean Architecture Solution for ASP.NET Core 3.1 soon?
I am very interested and I need the authorization, authentication and seedind DB parts.
Thanks again for your valuable work.
Josep
Hi, Thanks a lot for the feedback! Hope you liked the article.
Yes, As a matter of fact I am already building a Solution for Clean Architecture in ASP.NET Core 3.1 WebApi. It’s like 70% done I would say.
You can take a look at the repository here – https://github.com/iammukeshm/CleanArchitecture.WebApi
I am planning to release it in a couple of weeks in a well documented way / One-Click Install Template for Visual Studio 2019.
Thanks and regards.
OK, thanks for your reply…waiting for the template! ;-)))
Good articles so far. I appreciated & loved the way you shared your knowledge from article to new template, you are one of my inspiration.
Again, thank you for valuable job.
Hi, I have confused on choosing which architecture is better. which one gives better performance and less complexity,etc in .net core web api. can you share me better architecture name?
Onion / Hexagonal architecture is ideal for Monolith Applications. I have a full fledged Solution template that can get you started real easy.
Project Page – https://codewithmukesh.com/project/aspnet-core-webapi-clean-architecture/
Download the Extension from here –
https://marketplace.visualstudio.com/items?itemName=MukeshMurugan.CleanArchitectureWebApi
Regards
Cannot run the project.
Hi, What is the issue you face? Could i get more details? It runs fine for me
Regards
It is saying “This site can’t be reached”.
Thanks, I solved the problem with this link.
https://forums.asp.net/t/2144963.aspx?getting+error+This+site+can+t+be+reached+localhost+refused+to+connect+
I want to write unit test for controller. How Can I mock IMediator?
Hi Mukesh. Excellent post and Thank you
But I have a question. Adding EntityFrameworkcore to the application layer, creating a dependency for Entity Framework on the application layer. If I want to change the data access technology later, this would be a barrier. What is the solution for this?
Hi,
Yes, Ideally Adding EFCore onto the Application layer should be avoided. This was just a high level demonstration of Onion Architecture. To get a detailed study, please check out https://github.com/iammukeshm/CleanArchitecture.WebApi
The best way would be to rely on Repository layers that can create the necessary abstraction over the Data Access Technology. You can now move the EFCore to an Infrastructure Layer.
Regards
Thanks, Mukesh.
I recently started to learn .Net Core and found that there is what is called clean architecture and knew nothing about it. You have made it clear and simple though yet not confident with it because I know the coding part will be application-specific and hence will differ here and there. I am pleased with this Onion architecture and I wish to follow it more and more by implementing it in all my projects.
I will follow your other posts i.e. Authentication, Wrappers, Logging, Processing, e.t.c.
Can you also do Authorization (I think it will be easy to integrate, but I just think I love your style of coding, so I wish you would show your approach in Authorization/Role-based application with API)
Thanks a lot for your feedback!
Role Based Auth is already covered here for APIs – https://codewithmukesh.com/blog/aspnet-core-api-with-jwt-authentication/
Please do check it out and let me know.
Thanks and Regards
Hi Mukesh, I was new to building API’s with Microservice Architecture using ASP.net Core. I went through your articles and I can say ur aticles are one of the best. Can you please make articles on Logging, Validation and Transactional Behavior. I Know u have explaned the validator Behavior in MediatoR pattern But to keep things for tracking Can you please make an artcle on it.
Can you please create an article on Identity servers?
Hi, Thanks a lot for the feedback.
Yes, I am planning an entire series on Identity Server. It will be posted quite soon.
Thanks and Regards!
Hi. Good Work. Is’t a must to use a database if I wish to do only microservices?
your articles are well organized with deep details. keep it up. I am salute your time and efforts to share articles.
Do you have an example how integrate Unit Test projects with this onion architecture?
Thanks Mukesh!!
would be very great if you could add blazor project
Hi,
Thanks for your post :),
Why do you put interfaces in application service layer? We could put them in the domain core layer, and it is a more abstract approach !
Something that Steve smith mentioned in this post, All interfaces like services interfaces and repositories interfaces placed in inner center area of domain.
https://docs.microsoft.com/en-us/dotnet/architecture/modern-web-apps-azure/common-web-application-architectures#clean-architecture
Thanks for this nice project. Can you include Blazor and SignalR-API?
Hi! I am working on a dedicated Clean Architecture project for Blazor. You could give it a look – https://github.com/blazorhero/CleanArchitecture
It’s my first time at this website but oh man am I stunned. This is a great article and very clean implementation, cheers to you
Hi. Welcome to my blog 😛 I believe there are many more articles for you to enjoy as well 😉 I am currently with the blazor Clean Architecture template if that might interest you. – https://github.com/blazorhero/CleanArchitecture
Hi Mukesh,
A great article indeed.
I just wonder and want to know why all the samples we found with Entity framework? I have a big project to start and wish to write the logic in SQL stored procedures. Stored procedures because we find the easy maintenance and also easy to write the logic. And for this, wish to use ADO.Net without entity framework.
What would you suggest ?
In practical scenarios, you would actually want both EFCore and RAW SQL Queries for optimal performance. While ADO.NET is super fast, it’s very ideal for long queries with tons of joins. Whereas, EFCore comes with a lot features without compromising much on the performance. It gives a nice abstraction over the DB Provider as well. Meaning you can switch to another database technology with ease.
So, ultimately there is no actual answer. It all depends on your application design and performance optimization. But you will surely end up having both EF and ADO.NET working side by side.
Regards.
Really cool, Mukesh.
As a newbie in .NET, I would like to use this architecture in a personal project with a twist:
I already built the DB Model in SQL Server (all entities and constraints) and would like to use EF Data First as the starting point for the persistence layer – I may later make some changes in the classes created by EF Data First, which will be migrated to the DB.
How should I do that? What would be the step-by-step using this architecture?
Thanks
And if I choose Blazor Server project, I cant’t use this ?
excelente articulo. encontré el sitio por casualidad y me he leído las publicaciones que en su mayoría son muy interesantes y que no suele haber mucho por internet y además de todo con ejemplos claros y fáciles de seguir, para los principiantes que estamos iniciando en las arquitecturas empresariales y deseamos aprender a implementarlo en nuestros proyectos sin depender de un senior o simplemente seguir mejorando como programadores. saludos desde México, seguir asi!)
Brilliant
Amazing
Thank you very much for every article
I’m reading each article and implement with your clear steps and I am surprised every time with that super powerful results
Hi, Thanks a lot for the comment. Regards
Hi nice blog, but I got lost a bit on the EF section, would be nice if you have a video version of this
Hii,
I need onion architecture in blazor
Well, you are in luck 😛 I already have a complete implementation of Blazor Clean Architecture.
You can refer to – https://www.youtube.com/watch?v=j7BxKN7HYjk
Links are in the description section of the video.
Regards
Thanks for this contribution, I find it very practical when it comes to understanding it and I think my code will improve with these practices. Greetings from Argentina
Good stuff, well explained.
Quick note: SaveChanges should SaveChangesAsync so that the copied code from github matches.
Note for readers: This whole walk-thorugh works well for .Net Standard 2.0 core libs, for those who prefer to avoid the dll hell when linking to other (typically infra) libs that don’t have 2.1 builds. You’ll just need to use the 3.1.xxx versions (instead of 5.0.xxx) of various EF libs.
Thanks for the walkthrough, great information as always.
However, as a newcomer, I don’t know how to go about consuming the Api in an UI. Do you have any good resources to explain that process?
Sincerely,
Nicolas
I really want to appreciate you sir for pooling out a rich content like this, I followed your content as a guild to solved practical assessment given to me and I got a job of junior .NET Developer. Thanks a lot, am so happy today, I will ever be grateful to you for such a great content
Good Day !
hai Mukesh ,
recently I found your blog and it was extremely fantastic effort you are doing.
I am also a .Net developer working in N-Tier architecture. Your tutorial about Asp.Net core Onion architecture helped me a lot to learn.I would like ask some small doubts to improve my knowledge on asp.net core onion architecture.Can you please share how to create a function in “GetProductByIdQuery.cs” to join multiple tables from database using EF Code First
Thanks in advance
Hi Mukesh,
Nice article and great content. Could you please show us how to create unit tests within the context of this implementation (Onion architecture + CQRS + MediatR)
I would appreciate that a lot
Hi Mukesh, i was trying to implement the above code,
Got stuck, in which project should i place ‘public static class DependencyInjection’ this DependencyInjection class
Hi Mukesh. Great job with the architecture and thanks for sharing. There’s a problem with the template however that after authorizing and getting a valid token, the controllers with an [Authorize] attribute do not work, the error says “You are not authorized”. So, identity is not working correctly. Can you try this yourself and see what the problem is? Thank you.
Hi,
Which is the template that doesn’t work for you? Could you share the repo link?
Regards
Thank you for this valuable post.
You’ve said Application layer has Application-specific types and interface. Then why did you use .net standard instead of .Net Core for this layer?
Dear All,
How can I design my reports and export them as PDF in .net core??
it is a very important issue
BR
How to do connect with mysql with onion architecture
You have explained very well. Can we add Repository instead of using direct DbContext in Commands and Queries?
Yes, Infact you should use a Repository pattern always to keep a nice abstraction over the database. This also depends on the project requirement.
Check – https://github.com/fullstackhero/dotnet-webapi-boilerplate
This is a boilerplate that I am working on which uses Repository pattern as well.
Hello, I am a .Net architect working for a very very very wealthy company in the USA. I am promoting your framework as a solution. My gut instinct is, they will understand and welcome this initiative. If so, they have so much money, it would not surprise me if they reach out to you to either hire you or contract you. Is that a possibility? We can use the knowledge you have. Thanks.
Can I know which company is this? and which framework are you referring to ? fullStackHero?
You are the best, you helped me a lot to learn these patterns. Thanks a lot.
It could be great if you can update it with .net core 6.0 and include serilog logging, xunit testing
You can check fullstackhero! It’s on .NET 6 too.
https://github.com/fullstackhero/dotnet-webapi-boilerplate
Hello, this is really best tutorial about onion architecture,
I have questions,
First, where I put business logic, commonly called service, for example ProductService, where the logic before ProductCreateCommand called?
Second, I need to add ClosedXML to generate excel, where I can put that? in Application, Domain, or Presentation?
Thanks
Thanks for the very detailed post.
I have one concern can you help to explain. I see your comparison between N Layer and Onion architecture and the main difference is to eliminate coupling between layers which exists in N Layer. However, from my experience we can use Dependency Inversion in N Layer also so there is no tight coupling between layers in N Layer architecture. For example, EmployeeControler communicates to EmployeeService through interface, EmployeeService communicates to EmployeeService also through interface…
My question is what is the main difference between those architectures?
Mukesh, keep the lovely work up. Very useful articles you publish!
Thanks from the bottom of my heart!
Hi, Mukesh Murugan, Great job man! nice and clear explanation. I have a question it would be great if you take a moment and answer it. My question is can we use stored procedures in this onion architecture. If yes can you please give me a hint or a sample code. Thanks a lot man.
Hi Mukesh,
This architecture looks good for single project. Please help understand how can we do this if we have multiple modules in a project and we want have separate deployment for each module, however want to maintain consistency of nomenclature in each module. Can we create a base structure and whenever want to add a new project just simply inherit base class and the entire structure is copied.
This can help avoiding repetitive work and maintain consistency when working with multiple developers and modules in a large project.
Please help