Clean architecture in .NET and C#
In this article, I will show a brief introduction about Clean Architecture and also a practical example of a solution following the principles of Clean Architecture in .NET 6.
– What is Clean architecture? –
Clean Architecture is a software design philosophy. The main objective of this architecture is the ability to separate the code into its different responsibilities, make the code much more understandable in the present and future, testable and easy to integrate.
The overriding rule that makes this architecture work is the dependency rule. Code dependencies can only move from outer levels inwards, ie source code dependencies can only point inwards. The code of the inner layers cannot have knowledge of the functions of the outer layers.
The domain and application layers are at the center of the design. This is known as the core of the system. Core should not be dependent on data access and other infrastructure concerns.
To reverse the dependencies, interfaces or abstractions are added inside the Core that are implemented by layers outside of it.
Advantages of Clean architecture
Clean Architecture offers a number of benefits for software development, including:
- Makes code easier to maintain – Separating the different layers of the architecture makes code easier to maintain in the long term, since changes in one layer do not affect the other layers.
- Improves the scalability of the system: allows adding new functionalities to the system in a modular way, without affecting other parts of the code. Also, by separating the layers of the system, they can be independently optimized and scaled, making it easy to adapt the system to different situations and needs.
- Increases software quality – encourages the use of design patterns and good programming practices, resulting in cleaner, more readable, and maintainable code.
- Automated testing is much easier: By separating the layers of the system, testing can be done in isolation from the infrastructure, making it easier to develop unit and integration tests. Also, business rules can be tested without the user interface, database, web server, or any other external elements.
- It facilitates the evolution of the system: it facilitates the evolution of the system in the long term, since it allows it to adapt to changes in technologies, business requirements, etc. In addition, the separation of the system layers allows reuse of components and functionality in different parts of the system, which facilitates development and reduces maintenance costs.
- Independent of the database and anything external, you can swap Oracle or SQL Server for Mongo or anything else. Your trading rules are not tied to the database, they just don’t know anything about the outside world.
Clean Architecture is a methodology that helps develop scalable, maintainable and flexible software systems, by separating responsibilities into different layers and using design patterns and good programming practices. This translates into a cleaner, more readable and maintainable code, which facilitates the evolution of the system and increases the quality of the software.
– Main layers –
The domain layer encapsulates business rules (Enterprise business rules). The domain is not affected by external changes, as it does not have references to other layers.
Unit tests are performed here.
The application layer contains application business rules.
This layer defines interfaces that are implemented by external layers. For example, if the app needs to access a notification service, a new interface would be added to the app and an implementation would be created within the framework.
This layer implements CQRS and Command Query Responsibility Segregation (mediator) pattern, with each business use case represented by a single command or query.
Integration tests are performed here.
The Infrastructure layer contains classes for accessing external resources. These classes must be based on interfaces defined within the application layer.
- Web API using ASP.NET Core 6
- Open API with Swashbuckle
- Data access with Entity Framework Core 6
- UI using Angular 12
- CQRS with MediatR
- Object-Object Mapping with AutoMapper
- Validation with FluentValidation
- Automated testing with xUnit, FluentAssertions, Moq & Respawn
- Containerized with Docker
- Security using ASP.NET Core Identity + IdentityServer
The source code for this article can be found on GitHub