dotnet core: clean architecture in .net core 5 – intro


Our experience with Uncle Bob’s Clean Architecture in net core 5 is being very good. We used Jason Taylor’s clean Architecture template as the starting point. This approach uses the CQRS concept to subdivide all the internal business logic and make use of several “state of the art” libraries and concepts that creates an environment where the main application logic can be expressed with simplicity and isolated from other generic requirements like validations, DTO’s transformation, Authorization, etc.

Our experience with Uncle Bob’s Clean Architecture in net core 5 is being very good. We used Jason Taylor’s clean Architecture template as the starting point. This approach uses the CQRS concept to subdivide all the internal business logic and make use of several “state of the art” libraries and concepts that creates an environment where the main application logic can be expressed with simplicity and isolated from other generic requirements like validations, DTO’s transformation, Authorization, etc.

Let’s start from the beginning

What is “Clean Architecture”?

Clean architecture is a set of principles whose main purpose is to hide implementation details from the application’s domain logic.

In this way we keep the logic isolated, achieving a much more maintainable and scalable logic over time.

In Clean Architecture, an application is subdivided in concentric layers, and each layer has very well defined responsability. The most internals layers represent the core of the app and includes the main bussines logic, while most external layers includes the implementation of the services required for internal layers to do its work.

The main rule in clean architecture is the “dependency rule”, this mean that internal layers (the core) never depends on the implementation details (external layers), the dependency here is inverted. This is achieved by an extensive use of Dependency Injection. The core defines the interfaces it need to work, and the external layers provides an implementation for that interfaces and all is tied with Dependency Injection.

A good example of core isolation is the following: Imagine you have an application that need to consume resourses provided by an external API. Traditionally there are several ways to consume data

  1. The core iteself implements the api client. (Uncle Bob can have a heart attack if see you doing this!)
  2. Download a third party api client and add this library as a dependency in the core project.
  3. Write our own api client and add this project as a “referenced project” in our core project.

In terms of dependency, with this three options we create a hard dependency between our core app logic and the api client implementation.

Uncle Bob propose us a diffent idea: As the core know that it need external data, it defines an interface, and use that interface to consume the external data. After that we create another project, let’s call it “infrastructure.api.client” and add to this project a reference to the core project, now you can add your own implementation the the interfeces proposed by the core, so here the dependency is inverted, is the “infrastructure.api.client” the one that depends on the core, and not the core depening on a particular implementation

Ok, but how we put all together?

As the presentation layer is the entry point to our app, (web, CLI, winfors or a rest api). this external layer is the main responsible to start the process that tie all the services with the required implementation. As we stated previously, this is done via Dependency Injection. So, each external layer (the “infrastructure.api.client” in this example) will provide a method to bind its own implementation with the core interfaces. and the Presentation layer will call those methods.