What is Clean Architecture and why should I use it?

Introduction

Clean Architecture style focus on a loosely coupled implementation of use cases. Use cases as central organizing structure, decoupled from frameworks and technology details.

What is Clean Architecture?

With Clean Architecture, the Domain and Application layers are at the centre of the design which is known as the Core of the system. Business Logic places into these two layers, while they contain different kinds of business logic. They are seen as details and the business layers should not depend on Presentation and Infrastructure layers. Instead of having business logic depend on data access or other infrastructure concerns, this dependency is inverted: infrastructure and implementation details depend on the Application layer. This functionality is achieved by defining abstractions, or interfaces, in the Application layer, which are then implemented by types defined in the Infrastructure layer. A common way of visualizing this architecture is to use a series of concentric circles, similar to an onion architecture.

The Domain layer contains enterprise logic and types and the Application layer contains business logic and types. The difference is that enterprise logic could be shared across many systems, whereas the business logic will typically only be used within a system.

Core should not be dependent on data access and other infrastructure concerns so those dependencies are inverted. This is achieved by adding interfaces or abstractions within Core that are implemented by layers outside of Core.

All dependencies flow inwards and Core has no dependency on any other layer. Infrastructure and Presentation depend on Core, but not on one another.

How to Implement?

1. Domain Layer

Domain Layer implements the core, use-case independent business logic of the domain/system. By design, this layer is highly abstracted and stable. This layer contains a considerable amount of domain entities and should not depend on external libraries and frameworks. Ideally it should be loosely coupled even to the .NET Framework.

Domain project is core and backbone project. It is the heart and centre project of the Clean Architecture design. All other projects should be depended on the Domain project.

Domain layer contains:

    • Entities
    • Aggregates
    • Value Objects
    • Domain Events
    • Enums
    • Constants
2. Application Layer

Application Layer implements the use cases of the application based on the domain. A use case can be thought as a user interaction on the User Interface (UI). This layer contains all application logic. It is dependent on the domain layer, but has no dependencies on any other layer or project. This layer defines interfaces that are implemented by outside layers.

Application layer contains the application Use Cases which orchestrate the high-level business rules. By design the orchestration will depend on abstractions of external services (e.g., Repositories). The package exposes Boundaries Interfaces (in other terms Contracts or Ports or Interfaces) which are used by the User Interface.

Application layer contains:

    • Abstractions/Contracts/Interfaces
    • Application Services/Handlers
    • Commands and Queries
    • Exceptions
    • Models (DTOs)
    • Mappers
    • Validators
    • Behaviours
    • Specifications
3. Infrastructure Layer

This layer is responsible to implement the Contracts (Interfaces/Adapters) defined within the application layer to the Secondary Actors. Infrastructure Layer supports other layer by implementing the abstractions and integrations to 3rd-party library and systems.

Infrastructure layer contains most of the application’s dependencies on external resources such as file systems, web services, third party APIs, and so on. The implementation of services should be based on interfaces defined within the application layer.

Infrastructure layer contains:

    • Identity Services
    • File Storage Services
    • Queue Storage Services
    • Message Bus Services
    • Payment Services
    • Third-party Services
    • Notifications
      • Email Service
      • SMS Service
4. Persistence Layer

This layer handles database concerns and other data access operations. By design the infrastructure depends on Application layer. This project contains implementations of the interfaces (e.g., Repositories) that defined in the Application project.

For instance, an SQL Server Database is a secondary actor which is affected by the application use cases, all the implementation and dependencies required to consume the SQL Server is created on infrastructure (persistence) layer.

Persistence layer contains:

    • Data Context
    • Repositories
    • Data Seeding
    • Data Migrations
    • Caching (Distributed, In-Memory)
5. User Interface (Web/API) Layer

This layer is also called as Presentation. Presentation Layer contains the UI elements (pages, components) of the application. It handles the presentation (UI, API, etc.) concerns. This layer is responsible for rendering the Graphical User Interface (GUI) to interact with the user or Json data to other systems. It is the application entry-point.

User Interface layer depends on both the Application and Infrastructure layers, however, the dependency on Infrastructure is only to support dependency injection. This layer can be an ASP.NET Core Web API with Single Page Application (SPA like Angular, React) or it can be an ASP.NET Core MVC with Razor Views.
This layer receives HTTP Requests from users, and Presenters converts the application outputs into ViewModels that are rendered as HTTP Responses.

User Interface layer contains:

    • Controllers
    • Views
    • View Models
    • Middleware
    • Filters/Attributes
    • Web/API Utilities

Benefits of Clean Architecture

  • Maintainability and Extensibility – The separation of concerns in Clean Architecture allows developers to modify or replace components without affecting the rest of the application, making it more maintainable and extensible.
  • Framework Independence – Clean architecture can be used with ASP.NET (Core), Java, Python, etc. It doesn’t rely on any software library or proprietary code base.
  • Test-ability and Quality Assurance – By promoting the use of interfaces and DI, Clean Architecture simplifies the testing process and ensures higher code quality through rigorous testing.
  • Database Independent – Majority of application code has no knowledge of what database, if any, being used by the application. Often, this info will exist in a single class, in a single project that no other project references.
  • Flexibility for Technology Stack – With the core business logic isolated from external frameworks, Clean Architecture allows developers to switch or upgrade technologies with minimal impact on the application.
  • UI Independent – The UI project cares about the UI only. It has nothing to do with the implementation of business or data logic.

Conclusion

Clean Architecture in .NET Core offers a structured and systematic approach to building maintainable and scalable applications. By organizing the code base into distinct layers and adhering to the principles of separation of concerns and independence of frameworks, developers can create robust, testable, and flexible applications. Embrace Clean Architecture in your .NET Core projects to unlock its potential for long-term success and ease of maintenance.

What is Clean Architecture and why should I use it?
Scroll to top