Clean Architecture in a DotNet Core Microservice

Whether you call it Clean ArquitectureHexagonal Arquitecture or Onion Architecture it does not matter. What matters is the main concept: your dependencies between layers in your microservice (or application) should always go towards the middle as per the following diagram.


This means that if you follow Domain Driven Design when coding (and you should), your domain layer should be the first thing you would start developing because it contains the business logic and it should be in the middle. The domain layer should not know anything about any other layer, therefore it should not have any dependency towards any external layer.

The application layer would sit immediately above the domain layer, and its responsibility would be to orchestrate the domain logic, therefore its only dependency would be towards the domain layer.

Outside the domain and the application layer it is everything else, the framework, the infrastructure and the implementations that depend on any specific product. These external layers typically depend on the application or domain layer because they implement some of these inner layers interfaces or contracts. Also they can depend on any other external layer.

In the above diagram this external layer contains the web api layer if you are developing a web application because it would contain, for example, the AspNetCore Mvc Controllers and that's a specific technology. The controllers should never have any business logic, they are simply entry points to the application over the http protocol, therefore they accept read (GET) or write (POST, PUT, PATCH, DELETE) http verbs that should be received by the controllers' methods and these methods should simply delegate the use case interaction to the application layer and return the proper http response. In other words, your web api layer should only contain thin controllers where you inject the appropriate application services they rely on.

Also we can find here in the external layers the web api app or host layer, which is the place where the dependency injection container is configured and the registrations made. It also usually have the host or daemon that runs the application as in the case of web applications where it will contain the main program with the entry point that the server will execute.

Finally, among the external layers we can find any infrastructure implementation or code that directly depends on a specific product or environment. The most typical case of infrastructure layer code is for example a repository that uses a specific database like MongoDb or SqlServer and implements the interfaces that live in application or domain layer.


If you use Visual Studio, there is a great tool to Show the Project Dependency Diagram when you right click on a Visual Studio solution. This diagram will display all the different projects within the solution and the dependencies. If your domain layer does not depend on anything else (an exception being some external contracts, for example), your application layer depends only on the domain layer, and above them you find your infrastructure and framework layers, then it's very likely your architecture is a clean architecture.

The biggest advantage of using a clean architecture is that you can test completely your business logic without relying on any specific or third party product. You could switch from one product to another (e.g: from MongoDb to SqlServer database) without breaking any business logic test. That's why your business logic should only be in your domain layer, and nothing that you don't control or that it does not mean anything for your ubiquitous language should be in your domain layer.

I have an example of a typical microservice project structure implemented with AspNetCore 2.2.0 on this repository.

Comments