In the case of any development, Good Architecture is one of the significant aspects to develop modular, scalable, and maintainable applications. Different types of architectural design may vary as per their details. But one common thing always consists of all the architectural design, i.e., Separation of Concern. We can achieve this Separation of Concern concept by splitting the entire application into multiple layers. Clean Architecture is a software architecture pattern through which we can keep the code under control without any tidiness. The central concept behind the Clean Architecture in any application is to write down the code without any dependency that is unlikely to change. So, in this way, if we change the Framework version, database, or UI-related code, the Core of the application (Business Rules / Domain) does not require to change. It means in the application if we use any external dependency that is replaceable without making any code changes in the core system.
Overview of Clean Architecture
Clean Architecture patterns always focus on the loosely coupled implementation of the application layers. In the case of Clean Architecture, the Domain and Application layers always lie in the design center. These two layers are known as the Core System. All the enterprise-level logic and types are contained within the Domain layer. In comparison, all the business logic and classifications are included in the Application layer. This layer's primary difference is that Enterprise logic can be shared between the many application layers or systems. In contrast, the application or business logic will mainly be used within one system.
The core layer should not be dependent on any data access layers or any other infrastructure. We can achieve this by using or adding the interfaces or abstractions within the Core layer, which are usually implemented by layers outside the Core. For example, if we want to implement Repository design patterns, we can add an interface within the Core and its implementation within the infrastructure layer. So, in standard practice, all the dependencies flows must be inward towards Core Layer, and Core Layer does not have any dependency on any other layer. Of course, infrastructure and Presentation layers must depend on the Core. But both of them do not need to rely on each other.
The primary outcome of this type of architecture and design is that –
- Framework always needs to be independent. It does not require to use of any existing tool or framework.
- Code which is written must be easily Testable. Since the Core layer does not depend on any external process, we can develop the automated tests quickly.
- UI layer must be independent of the business logic. So that we can change the UI technology at any time if required.
- Also, the entire architecture needs to be independent of the data access layer. So, we can move from one database to another, like SQL Server to Cosmos DB or others at any point in time.
Common Architectures in Asp.Net Core
In the case of traditional .NET Applications, it is always deployed as a Single Unit related to an executable or a single web-based application running in the IIS app domain. It is the simple approach of the deployment model. And this Model is used in the case of many internal and external small public applications. But despite single unit deployment, some business applications always benefit from the logical separation into several layers.
A Monolithic application is the best example of a Single unit application, which is entirely self-contained in behavior or functionality. Of course, these types of applications maybe interact with other services or data access layers. Still, it always runs within its process when performing its operation, and the entire application is deployed as a single unit. For this type of application, if we require to scale the application horizontally, we need the whole application to be duplicated across multiple servers or VMs.
In the case of application architecture, the smallest possible number of projects is one. In this architecture, the application's business logic is a single project, compiled into a single assembly, and deployed as a single unit. A new ASP.Net Core Project, either we create that using Visual Studio or by the command line, always starts as a Single "all-in-one" monolith. It always contains all of the application's behavior, including presentation and data access logic. The image shows the file structure of a single project app.
In the case of this type of Single Project Scenario, we can achieve the separation of concerns with the help of using folders. The default template includes different folders for MVC Pattern responsibilities like Models, Views, and Controllers. Also, we can add additional folders like Data and Service as per our requirements. But this simple, single-project-based monolithic solution always has some disadvantages. For example, as the size of the projects increases along with the complexity, the number of files and folders will increase. In this way, file management becomes very tough to maintain.
As the application complexity increases, one of the best ways to manage it is to break down the application's responsibility or functionality. This approach follows the separation of concern principle and helps us organize a large codebase. With the help of layered architecture, we can achieve many advantages except code organization. Using the code into different layers can reuse the standard low-level functionality throughout the application. Furthermore, this approach allows us to standardize the application on a single implementation followed by the Don't Repeat Yourself (DRY) principle.
In a layered architecture, applications are broken down into multiple layers, and each layer can communicate with other layers. This architecture helps us to achieve encapsulation. Because when we need to change a particular layer, it will affect only those layers that work with it. So, by reducing the layer's dependency on each other, we can minimize the impacts of changes which can be mitigated so that a single change does not impact the entire application.
The most common applications always follow the Traditional N-Layer Architecture.
As mentioned earlier, this architecture always contains the layers, generally abbreviated as UI, BL (Business Logic Layer), and DAL (Data Access Layer). Users always request the UI in this architecture, and UI layers communicate the BL layers. BL layer then communicates with the data access layers. However, UI Layer can't directly communicate with the DAL layers. The below images show the example solution structure where the application breaks down into three projects as per the responsibility or layers.
Clean Architecture is a better way to organize moderate to high complexity applications. It helps us separate dependencies and keep them isolated from business logic and the application's domain model. ASP.NET Core works entirely with the Clean Architecture approach, provided that the initial solution structure is set up correctly. Using a solution template in ASP.NET Core can help ensure you get your application started on the right track.