Skip to content

Architecture ‐ Clean Architecture

Full Stack edited this page Mar 3, 2025 · 2 revisions

Articles, References related to architecture style.

What is Clean Architecture

Its about designing loosely coupled systems that can independently scale to supply the demand

Clean architecture refers to software architecture. Instead of relying on data access for business logic, the application core is responsible for infrastructure and implementation details. In the application core, we can define abstractions, or interfaces, to achieve this functionality. There are various types defined at the infrastructure layer that can be used to implement clean architecture.

image

Principles

  • Maintainability
  • Testability
  • Loose Coupling / Separation Concerns

Domain Layer

  • Entities
  • Value Objects
  • Domain Events
  • Domain Services
  • Interfaces
  • Exceptions
  • Enums

Application Layer

  • CQRS

Infrastructure Layer

Presentation Layer

Cross-Cutting Concerns

Authentication & Authorization

Logging

  • It's vital for debugging, monitoring application health, and tracking user activities and system anomalies. In the context of Clean Architecture, logging must be implemented in a way that maintains the separation of concerns.

Exception management

Validation

  • Input validation
  • Business rule validation

Input validation checks for the correctness and format of the data (like string length, number ranges, and date formats), ensuring it meets the basic criteria before processing.

On the other hand, business rule validation is more about ensuring that the data adheres to your domain's specific rules and logic.

Caching

When implementing caching, it's crucial to consider:

  • What to Cache: Identify data that is expensive to compute or retrieve and stable enough to be cached.
  • Cache Invalidations: Determine when and how cached data should be invalidated.
  • Cache Configuration: Configure cache settings like expiration and size appropriately.
  • Messaging
  • Security
  • Configuration

References

Traditional N Tier

  • It has layers such as UI, BLL (Business Logic Layer), and DAL (Data Access Layer).
  • Presentation of any page will be a part of the UI Layer. In the UI layer, users can make requests. BLL interacts with these requests.
  • It depends on DAL. BLL holds the logic in the application. BLL calls DAL for data access requests.
  • DAL holds the data access to all the implementation details. DAL depends on the existence of the Database.
  • One key disadvantage of this architecture is that the compile time dependencies run from the top to bottom.The main User Interface layer depends upon the BLL and this BLL is dependent on the DAL. This means that the BLL, which holds the most important logic in the application, depends upon the data access layer.
  • So, business logic testing is much more difficult as it always requires a test database.
  • As a solution, dependency inversion principle is used.

Clean Architecture Design

  • In this type, domain and Application layers remain at the core of the design, which is called the center of the design.
  • Unlike Traditional “N-Layer” architecture, the clean architecture is independent of the database, UI layer, Framework, and several other external agencies.
  • The clean architecture puts business logic & application model at the center of the application.
  • It has inverted dependency, the infrastructure and implementation details will depend on the application core.

image

  • Another representation image image

There are 3 layers in the Clean Architecture: The domain layer or infrastructure layer is in the center and surrounded by the application core layer and the outer layer consists of user interfaces.

Compile-time dependencies are represented by solid arrows & runtime-only dependency is represented by dashed arrows in the following diagram. It will become very easy to write automated unit tests & the reason is that the Application Core doesn’t depend on Infrastructure. The applications where UI projects, Infrastructure & Application Core runs as a single unit, are called monolithic applications.

There are interfaces defined in the application core. At the compile time the UI layer works with them. The Infrastructure layer will define implementation types, & UI layer shouldn’t know about those types. However, when the app executes, it requires these implementation types. Implementation types need to be present and must be wired up with the Application’s Core interfaces. Also, with the help of dependency injection, we shall be able to do the above mentioned things.

Important design Rules

  • Model all business rules and entities in the core project
  • All dependencies flow towards the core project
  • Inner projects define interfaces and outer projects implement them (Dependency Inversion Principle)

When to use clean architecture

  • want to focus on domain model rather than infrastructure
  • want to create highly testable architecture
  • want architecture help on enforcing policies rather than relying upon the developers to consistently do the right thing.

Benefits

  • Clean architecture provides you with a cost-effective methodology that helps you to develop quality code with better performance and is easy to understand.
  • Independent of database, frameworks & presentation layer. One can change the user interface at any time without changing the rest of the system or business logic.
  • Unlike Oracle or SQL Server database, business rules are not bound to any specific database, so one can use BigTable, MongoDB, CouchDB, or something else to implement the business rules. Also, clean architecture doesn’t depend on the existence of some libraries, which are having features of laden software.
  • Clean architecture is highly testable, one can check business rules without any other external elements or even without the UI, Web server, or Database.
  • Clean architecture is independent of any external agency, one can say that business rules are unknown to the outside world.
  • Domain object holds important actions and events of the business use case.
  • Domain model can have additional functionality defined within, so that it can be independently tested.

Example

image

What belongs to ASP.NET Core Web(Domain Layer)?

  • One can have all of ASP.NET Core & ASP.NET Core MVC Types or some of these in addition to any DTO types such as ViewModel or API Model etc.
  • ASP.NET Core Web App may include controllers, Models, ViewModels, ASP.NET Core Identity, Response Caching Filters, Model Validation Filters or several other filters, etc.

What about Application Core?

  • All of the Domain ModelTypes belong to Application Core.
  • Interfaces, Business Services, Domain Events, Value Objects, POCO Entities, Application Exceptions, Aggregates, Specifications etc will be a part of Application Core Project.

image

What resides in the Infrastructure?

  • The communications out of the app’s process belong to Infrastructure.
  • Like if someone wants to communicate out of the app, through an SMS so that can also be done through the app.
  • There will be Redis Cache Service, Azure Service bus Accessor, InMemory Data Cache, EF DbContext or SMS Service, Email Service, Other API Clients in infrastructure project.
  • Here in the database, we can use database link SQL to be a part Data Source.
  • Third-Party Services can be GitHub API, SendGrid API, Twilio API.

Projects

Explanation

Application Layer

  • Application core layer contains all the business logic along with entities, domain services and interfaces. It should have minimal dependencies on databases, instead we expect it should have interface and domain model types including entities, value objects aggregates. There are domain services which will have logic in them that affects multiple entities or aggregates.
  • Also custom exceptions should be in the application layer. It is helpful to know when exceptions occur. Apart from that, the application layer contains domain events, event handlers and specifications which are the way to encapsulate the query into a class.
  • For services to pass the data to higher layers, there should be Data Transfer Objects (DTOs). There can be validators in the core project like “fluentvalidation” which is used to validate the objects which are passed in the controller. Also ”enums” can be there along with custom guard clauses.
  • Types of Application Layer Application core include interfaces, domain services, specifications, custom exceptions, protection clauses, domain events, handlers, and more.

Infrastructure Layer

It depends on the Application layer for the business logic. It implements an interface from the application layer and provides functionality for accessing external systems. It includes repositories that talk to the database, the Entity Framework DbContext and necessary migration files for the communication with the database. The infrastructure layer also contains API Clients, File System, Email/SMS and System Clock. Also, there are services which implement interfaces defined in Application layer therefore, all interfaces primarily go into application core but some interfaces will go in infrastructure. So basically it works on the database and external API calls.

  • Types of Infrastructure Layer
  • EF Core DbContext
  • Data access implementation types like Repositories, Web services, and file logger.

User Interface Layer

This layer is the access factor to the application from the user’s perspective. It contains the MVC stuff like Controller, Views or Razor Pages, ViewModels, etc. It can have custom model binders, custom filters, and custom middleware. Tag helpers are also part of these layers. There are some built-in tag helpers like Html tag helpers, image tag helpers, label tag helpers, etc. Model binding or custom model binding is also part of the UI layer.

  • Types of UI Layer UI Layer has Controllers, Views/Razor Pages, ViewModels, Custom middlewares, Custom filters, and Startup class.

Pros and Cons of Clean Architecture: Clean Architecture offers several advantages, including:

  1. Maintainability: The clear separation of concerns and independent layers facilitate easier maintenance and updates without impacting the entire system.

  2. Flexibility: The architecture’s decoupling from frameworks and technologies allows for easy adoption of new tools or changes to the technology stack.

  3. Testability: The clear separation of dependencies and the ability to isolate components during testing ensures comprehensive and reliable unit testing.

However, Clean Architecture also has some drawbacks to consider:

  1. Increased Complexity: The layered structure and strict dependency rules may introduce additional complexity, especially in smaller projects with simpler requirements.

  2. Initial Overhead: Implementing Clean Architecture requires careful planning and upfront investment in designing the architecture and defining interfaces, which may require more time and effort.

Pros and Cons of Domain-Driven Design: Domain-Driven Design offers several advantages, including:

Domain Expert Collaboration: DDD encourages active collaboration between developers and domain experts, ensuring a deep understanding of the business domain and more accurate modeling. Scalability and Adaptability: DDD’s bounded contexts and modular approach allow teams to work independently, supporting scalability and adaptability to changing requirements. Evolutionary Design: DDD embraces an iterative and incremental design process, allowing the domain model to evolve with changing business needs. However, there are a few considerations to keep in mind:

Learning Curve: DDD requires learning new concepts and patterns, which may initially pose a learning curve for developers unfamiliar with the approach. Complexity Management: Properly defining and managing bounded contexts and ensuring their integration can be challenging, especially in large and complex systems.

Commonalities and Differences: While Clean Architecture and DDD are distinct concepts, they also share common aspects:

Separation of Concerns: Both approaches emphasize the separation of concerns to achieve maintainable and modular codebases. Testability: Both Clean Architecture and DDD promote testability by encouraging the isolation of dependencies and unit testing at various layers. In terms of their differences, Clean Architecture primarily focuses on the overall structure of a software system, whereas DDD centers on modeling the core business domain. Clean Architecture addresses architectural layers and dependency management, while DDD provides principles and patterns for domain modeling and collaboration with domain experts.

What is the difference between Clean Architecture vs DDD?

Both focus on separating the domain code from the application and infrastructure code. But that is where the similarities end.

In Clean/Hexagonal/Onion (or CHO in short) architecture, the goal of this decoupling is testability and modularity with intended effect being that the "core" of our software can be reasoned about in isolation from rest of the world.

In DDD, the main goal is to establish common language with the business experts. The separation of the domain from rest of the application code is just a side effect of this main goal. It also has some say about the design of classes as entities and aggregates, but that is only within the domain itself. It has nothing to say about design outside the domain code.

In practice, you might find that you use both at the same time. You use CHO architecture to design the whole structure of the system, with the "domain core" being isolated in it's separate modules. And then you use DDD to design this domain core in collaboration with domain experts and possibly by using DDD concepts like Entities and Aggregates.

Whitepapers

References

Clone this wiki locally