Onion Architecture in ASP - NET Core With CQRS - Detailed PDF
Onion Architecture in ASP - NET Core With CQRS - Detailed PDF
Onion Architecture in ASP - NET Core With CQRS - Detailed PDF
U a
En este artículo, hablaremos sobre Onion Architecture In ASP.NET Core y sus ventajas. También construiremos juntos un WebApi que siga
una variante de Onion Architecture para que podamos ver por qué es importante implementar una arquitectura de este tipo en sus
próximos proyectos. Puede encontrar el código fuente de esta implementación en mi GitHub.
Descargo de responsabilidad : Este es un artículo bastante grande con alrededor de 3500+ palabras. Marque esta página y continúe 😀
Tabla de contenidos
1. La necesidad de seguir una arquitectura
1.1. Niveles de Capa Vs
2. Breve descripción general de la arquitectura de capa N
3. Desventajas de la arquitectura de capa N
4. Introducción a la arquitectura de la cebolla
5. Implementación de la arquitectura de la cebolla en ASP.NET proyecto WebApi core
5.1. Con guración de la estructura de la solución
5.2. Adición de Swagger al proyecto WebApi
5.3. Adición de las entidades al proyecto de dominio
5.4. Adición de las interfaces y paquetes necesarios en la capa de aplicación
5.5. Implementación de MediatR para operaciones CRUD
5.6. Con guración de EF Core en el proyecto de persistencia
5.7. Generar las migraciones y la base de datos
5.8. Adición de versiones de API
5.9. Con guración de los controladores
5.10. Pruebas
6. Ventajas de la arquitectura de cebolla en ASP.NET Core
7. Mejoras adicionales
8. Arquitectura limpia con ASP.NET Core WebApi – Plantilla
9. Resumen
Niveles de Capa Vs
Cuando solo hay una separación lógica en la aplicación, podemos denominarlo como capas o capas N. En los casos en que hay una
separación física y lógica de preocupaciones, a menudo se conoce como aplicación de n niveles donde n es el número de separaciones. 3 es
el valor más común de N. En este artículo, trataremos la Arquitectura en Capas.
Esta capa puede ayudar en la separación de preocupaciones, subdividiendo la solución en unidades más pequeñas para que cada unidad sea
responsable de una tarea especí ca y también para aprovechar la abstracción. Para proyectos de escala media a mayor donde trabajan
varios equipos, las capas tienen ventajas muy obvias bajo las mangas. Permite a un equipo especí co o individuo trabajar en una capa en
particular sin perturbar la integridad de los demás. Hace que sea mucho más fácil realizar un seguimiento de los cambios mediante el control
de código fuente.
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 1/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
Antes de entrar en Onion Architecture en ASP.NET Core, primero actualicemos nuestros conocimientos sobre arquitectura de capa N.
En lugar de construir una estructura altamente desacoplada, a menudo terminamos con varias capas que dependen unas de otras. Esto es
algo realmente malo en la creación de aplicaciones escalables y puede plantear problemas con el crecimiento de la base de código. Para
mantenerlo claro, en el diagrama anterior podemos ver que la capa de presentación depende de la capa de lógicas, que a su vez depende del
acceso a los datos y así sucesivamente.
Por lo tanto, estaríamos creando un montón de acoplamientos innecesarios. ¿Es realmente necesario? En la mayoría de los casos, la capa de
interfaz de usuario (presentación) también se acoplaría a las capas de acceso a datos. Esto derrotaría el propósito de tener una arquitectura
limpia, ¿sí?
En N Layer Architecture, la base de datos suele ser el núcleo de toda la aplicación, es decir, es la única capa que no tiene que depender de
nada más. Cualquier pequeño cambio en la capa Business Logics o en la capa de acceso a datos puede resultar peligroso para la integridad
de toda la aplicación.
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 2/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
Domain and Application Layer will be at the center of the design. We can refer to these layers at 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 di erence 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-speci c types and interface. 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 and DIP or Dependency Inversion Principle.
For example, If your application want’s to send a mail, We de ne 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.
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.
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, or a Layer speci cally made to generate JWT Tokens for Authentication or even a Hang re
Layer. You will understand more when we start Implementing Onion Architecture in ASP.NET Core WebApi Project.
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 3/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
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
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 4/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 5/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
Let’s start adding the required projects. Firstly, under 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?
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 6/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
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.)
Similary, 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.
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 7/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
Finally, in the Presentation layer, add a new ASP.NET Core 3.1 WebApi Project and name it WebApi.
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 8/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
This is what we will be having right now. You can see the clear seperation of concerns as we have read earlier. Let’s start build up the
architecture now.
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 9/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
Install the Following packages ot the WebApi Project via Package Manager Console
1. Install-Package Swashbuckle.AspNetCore
2. 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 Con gureServices
method.
1. #region Swagger
2. services.AddSwaggerGen(c =>
3. {
4. c.IncludeXmlComments(string.Format(@"{0}\OnionArchitecture.xml", System.AppDomain.CurrentDomain.Base
5. c.SwaggerDoc("v1", new OpenApiInfo
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 10/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
6. {
7. Version = "v1",
8. Title = "OnionArchitecture",
9. });
10.
11. });
12. #endregion
1. #region Swagger
2. // Enable middleware to serve generated Swagger as a JSON endpoint.
3. app.UseSwagger();
4.
5. // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
6. // specifying the Swagger JSON endpoint.
7. app.UseSwaggerUI(c =>
8. {
9. c.SwaggerEndpoint("/swagger/v1/swagger.json", "OnionArchitecture");
10. });
11. #endregion
Next, we will need to add the XML File (For Swagger Documentaion). To do this, right click the WebApi Project and go to propeties. In the Build
Tab enable the XML Documentation le and give an appropriate le name and location. I have added the xml le 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.
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 11/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
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 nd a launchsettings.json le. This le holds all the con guration required for
the app launch. Change the launch URL to swagger. Thus, swagger will open up by default every time you run the application. This helps you
save some time.
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 12/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
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.
Now add a Product Class that inherits the Id from the BaseEntity. Create a new class Entities/Product.cs in the Domain Project.
1. Install-Package MediatR.Extensions.Microsoft.DependencyInjection
2. Install-Package Microsoft.EntityFrameworkCore
We have a Entity named Product. Now we need to establish this class as a Table using Entity Framework Core. So we will need a
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 a 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, tommorow, you need a di erent
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
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 this 100 lines of code to the Startup.cs to register them in the container? That would be insane in 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.
Here we will just Add Mediator to the service collection. We will implement Mediator pattern later in this tutorial.
And all you have to do in the WebApi’s Startup class in just add one line. This essentially registers all the services associated with the
Application Layer into the container. Quite handy, yeah?
1. services.AddApplication();
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 14/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
I have already written a detailed article on MediatR and CQRS pattern 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 le. 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.
UpdateCommand –
https://github.com/iammukeshm/OnionArchitecture/blob/master/Application/Features/ProductFeatures/Commands/UpdateProductCommand.cs
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 15/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
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
So Far So Good?
Stay up to date! Get all the latest & greatest articles / in depth Guides on .NET Core / ASP.NET Core
delivered straight to your inbox. Subscribe now!
Name
Subscribe
1. "ConnectionStrings": {
2. "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=onionDb;Trusted_Connection=True;Multip
3. }
With the CRUD logics out of the ways, let’s setup EFCore in the Persistence Layer and try to generate a database. Install the following
packages to the Persistence Project.
1. Install-Package Microsoft.EntityFrameworkCore
2. 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.
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.
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 16/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
And in the Startup class/ Con gureServices method of the WebApi Just Add the following line. You can now see the advantage of this kind of
approach.
1. services.AddPersistence(Configuration);
1. Install-Package Microsoft.EntityFrameworkCore.Tools
2. Install-Package Microsoft.EntityFrameworkCore.Design
Now, open up the package manager console and select the Persistence project as the default prject (as mentioned in the sceenshot 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.
1. add-migration Initial
2. update-database
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 17/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
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.
1. Install-Package Microsoft.AspNetCore.Mvc.Versioning
In the Startup/Con gureServices of the API project, add these lines to register the Versioning.
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 18/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
4. {
5. // Specify the default API Version as 1.0
6. config.DefaultApiVersion = new ApiVersion(1, 0);
7. // If the client hasn't specified the API version in the request, use the default API version number
8. config.AssumeDefaultVersionWhenUnspecified = true;
9. // Advertise the API versions supported for the particular endpoint
10. config.ReportApiVersions = true;
11. });
12. #endregion
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 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-de ne the
API Versioning route nor the Mediatr object. But we will just add the BaseAPI Controller as the base class. Get it? I will show it in
implementation.
Add new Empty API Controller in the Controllers folder and name it BaseApiController.
1. using MediatR;
2. using Microsoft.AspNetCore.Http;
3. using Microsoft.AspNetCore.Mvc;
4. using Microsoft.Extensions.DependencyInjection;
5.
6. namespace WebApi.Controllers
7. {
8. [ApiController]
9. [Route("api/v{version:apiVersion}/[controller]")]
10. public abstract class BaseApiController : ControllerBase
11. {
12. private IMediator _mediator;
13. protected IMediator Mediator => _mediator ??= HttpContext.RequestServices.GetService<IMediator>(
14. }
15. }
You can see that we are adding the API Versioning data to the route attribute and also creating a 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.
1. [ApiVersion("1.0")]
2. public class ProductController : BaseApiController
3. {
4. /// <summary>
5. /// Creates a New Product.
6. /// </summary>
7. /// <param name="command"></param>
8. /// <returns></returns>
9. [HttpPost]
10. public async Task<IActionResult> Create(CreateProductCommand command)
11. {
12. return Ok(await Mediator.Send(command));
13. }
14. /// <summary>
15. /// Gets all Products.
/// /
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 19/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
16. /// </summary>
17. /// <returns></returns>
18. [HttpGet]
19. public async Task<IActionResult> GetAll()
20. {
21. return Ok(await Mediator.Send(new GetAllProductsQuery()));
22. }
23. /// <summary>
24. /// Gets Product Entity by Id.
25. /// </summary>
26. /// <param name="id"></param>
27. /// <returns></returns>
28. [HttpGet("{id}")]
29. public async Task<IActionResult> GetById(int id)
30. {
31. return Ok(await Mediator.Send(new GetProductByIdQuery { Id = id }));
32. }
33. /// <summary>
34. /// Deletes Product Entity based on Id.
35. /// </summary>
36. /// <param name="id"></param>
37. /// <returns></returns>
38. [HttpDelete("{id}")]
39. public async Task<IActionResult> Delete(int id)
40. {
41. return Ok(await Mediator.Send(new DeleteProductByIdCommand { Id = id }));
42. }
43. /// <summary>
44. /// Updates the Product Entity based on Id.
45. /// </summary>
46. /// <param name="id"></param>
47. /// <param name="command"></param>
48. /// <returns></returns>
49. [HttpPut("[action]")]
50. public async Task<IActionResult> Update(int id, UpdateProductCommand command)
51. {
52. if (id != command.Id)
53. {
54. return BadRequest();
55. }
56. return Ok(await Mediator.Send(command));
57. }
58. }
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.
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 20/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
Highly Testable – Since the Core has no dependencies on anything else, writing automated tests are exible,
Database Independent – Since we have a clean separation of data access, it is quite easy to switch between di erent database providers.
Switchable UI Layer (Presentation) – Since we are keeping all the crucial logics 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
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 21/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
However, I have covered 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.
I am planning to build a fully- edged 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.
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 22/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
Buy me a coffee
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 Stu . Let me know
your feedback and the scopes of improvement in this approach. You can nd the entire source code on my Github Repository. Feel free to
fork it and make necessary contributions if you feel so 😀 Happy Coding 🙂
16 Shares
58 Comments
Victor on June 18, 2020 at 9:41 pm
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
stu .
Reply
Reply
Keep posting!
Reply
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 23/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
Hi. Thanks for your lovely feedback. Hoping to bring in more rich articles.
Thanks and Regards.
Reply
This way developers can really learn how the onion architecture is implemented.
Reply
Reply
Reply
Reply
Reply
Reply
Reply
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 24/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
Reply
Reply
https://github.com/louthy/language-ext/tree/main/Samples/Contoso
https://leanpub.com/practical-functional-CSharp
Reply
Reply
Reply
Reply
Reply
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 25/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
yes started with very good notion but ending up few things which is not really great and can be modi ed in next
version of this boilerplate code
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
Reply
Reply
Authentication, Response Wrappers, Error Logging and Job Processing is already covered in my other articles.
Here are the links –
https://www.codewithmukesh.com/blog/aspnet-core-api-with-jwt-authentication/ (Auth)
https://www.codewithmukesh.com/blog/hang re-in-aspnet-core-3-1/ (job processing)
https://www.codewithmukesh.com/blog/serilog-in-aspnet-core-3-1/ (error logging)
https://www.codewithmukesh.com/blog/pagination-in-aspnet-core-webapi/ (wrappers & paginations)
Regards.
Reply
Install-Package MediatR.Extensions.Microsoft.DependencyInjection
Install-Package Microsoft.EntityFrameworkCore
—————————————————————————————————-
Reply
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 26/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
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:
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/
Reply
Reply
Reply
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 e ectively the same as leaking infrastructure and
presentation layer into application layer, you’re bound to the technologies and cannot replace them with anything else.
Reply
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.
Reply
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 27/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
Reply
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).
Reply
Reply
Reply
Reply
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.
Reply
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 28/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
Regards.
Reply
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.
Reply
Thanks for sharing, and I am currently working on a full edged Clean Architecture for WebApi.
Regards
Reply
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?
Reply
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 29/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
here. Also, as the application scales up, doesn’t your repo count grow too unnecessarily? Please correct
me if I am wrong
Reply
“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 bene ts:
– your domain layer can de ne 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 de ned your own API over the
raw database and your request handlers will use this API
– per the previous point, database-related complexity is con ned 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.
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 30/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
Reply
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 di erent request types, where commands alter state and may
introduce side e ects, while queries are read-only and side-e ect 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 di erent data stores,
where the query store is generally optimized for read e ciency, while the command store is optimized for processing
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 31/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
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
Reply
Reply
Reply
Reply
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 🙂
Reply
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 32/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
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.
Reply
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 🙂
Reply
Reply
CQRS is something that makes you controllers THIN. It is always a good practise to follow a well-de ned 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 proo ng 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
Reply
Thanks for this great article. I suppose I can’t use UnitOfWork pattern and generic repo even with Onion architecture. Could
you con rm (or not)
thanks,
Reply
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 33/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
Reply
Reply
Reply
Reply
Reply
Reply
Trackbacks/Pingbacks
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 34/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
1. The Morning Brew - Chris Alcock » The Morning Brew #3020 - […] Onion Architecture In ASP.NET Core With CQRS – Detailed – Mukesh
Murugan […]
Suscríbete a mi newsletter
Unirse a mi lista de correo para recibir noti caciones sobre mis últimos artículos, tutoriales y guías para principiantes en .NET Stack con C- y cualquier otra
cosa con la que pueda relacionarse como desarrollador.
Nombre
Correo electrónico
subscribir
CATEGORÍAS
.NET Core
Api
ASP.NET Core
Blazor
Codi cación
Patrones de diseño
ETIQUETAS
.NET Core Api asp.net núcleo Estructura del proyecto Blazor C# Cqrs Ide Mediador Serilog Registro estructurado Visual Studio
SEGUIR CODEWITHMUKESH
¡APOYENME!
Cómprame un café
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 35/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
Related Articles
In this article, we will learn how to use JQuery Datatable in ASP.NET Core with Server Side Processing. We will also...
READ MORE
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 36/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
Let's go through a popular way of Building Applications - Microservice Architecture in ASP.NET Core. In this detailed...
READ MORE
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 37/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
In this article, we will learn all about Dapper in ASP.NET Core and make a small implementation to understand how it...
READ MORE
Like my Work?
Join my mailing list to be noti ed about my latest Articles, Tutorials, and Beginner's Guides on .NET Stack using
C# and anything else that you may relate to as a developer.
Name
Subscribe
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 38/39
7/26/2020 Onion Architecture In ASP.NET Core With CQRS - Detailed
https://www.codewithmukesh.com/blog/onion-architecture-in-aspnet-core/ 39/39