Reader small image

You're reading from  Architecting ASP.NET Core Applications - Third Edition

Product typeBook
Published inMar 2024
Reading LevelIntermediate
PublisherPackt
ISBN-139781805123385
Edition3rd Edition
Languages
Right arrow
Author (1)
Carl-Hugo Marcotte
Carl-Hugo Marcotte
author image
Carl-Hugo Marcotte

Carl-Hugo Marcotte is a software craftsman who has developed digital products professionally since 2005, while his coding journey started around 1989 for fun. He has a bachelor's degree in computer science. He has acquired a solid background in software architecture and expertise in ASP.NET Core through creating a wide range of web and cloud applications, from custom e-commerce websites to enterprise applications. He served many customers as an independent consultant, taught programming, and is now a Principal Architect at Export Development Canada. Passionate about C#, ASP.NET Core, AI, automation, and Cloud computing, he fosters collaboration and the open-source ethos, sharing his expertise with the tech community.
Read more about Carl-Hugo Marcotte

Right arrow

Layering and Clean Architecture

In this chapter, we explore the inherent concepts behind layering. Layering is a popular way of organizing computer systems by encapsulating major concerns into layers. Those concerns are related to a computer vocation, such as data access, instead of a business concern, such as inventory. Understanding the concepts behind layering is essential, as many concepts and applications leverage layers.

We start this chapter by exploring the initial ideas behind layering. Then, we explore alternative ways to structure our layered applications that can help us solve different problems. We use anemic models and rich models and expose their pros and cons. Finally, we quickly explore Clean Architecture, an evolution of layering, and a modern way to organize layers.

This chapter lays out the evolution of layering, starting with basic, restrictive, and even flawed techniques, and then gradually moves toward more modern patterns. This journey should help...

Introducing layering

Now that we’ve explored a few design patterns and played with ASP.NET Core, it is time to jump into layering. In most computer systems, there are layers. Why? Because it is an efficient way to partition and organize units of logic together. We could conceptually represent layers as horizontal software segments, each encapsulating a concern.

Classic layering model

Let’s start by examining a classic three-layer application design:

Figure 14.1: A classic three-layer application design

The presentation layer represents any user interface that a user can interact with to reach the domain. It could be an ASP.NET Core web application, WPF, WinForms, Android, or any other presentation layer alternative.

The domain layer represents the core logic driven by the business rules; this solves the application’s problem. The domain layer is also called the business logic layer (BLL).

The data layer represents the bridge between...

Responsibilities of the common layers

In this section, we explore the most commonly used layers in more depth. We do not dig too deep into each one, but this overview should help you understand the essential ideas behind layering.

Presentation

The presentation layer is probably the easiest layer to understand because it is the only one we can see: the user interface. However, the presentation layer can also be the data contracts in case of a REST, OData, GraphQL, or other types of web service. The presentation layer is what the user uses to access your program. As another example, a CLI program can be a presentation layer. You write commands in a terminal, and the CLI dispatches them to its domain layer, executing the required business logic.

The key to a maintainable presentation layer is to keep it as focused on displaying the user interface as possible with as little business logic as possible.

Next, we look at the domain layer to see where these calls go.

Domain...

Abstract layers

This section looks at abstract layers using an abstract data layer implementation. This type of abstraction can be very useful and is another step closer to Clean Architecture. Moreover, you can abstract almost anything this way, which is nothing more than applying the Dependency Inversion Principle (DIP).

Let’s start with some context and the problem:

  • The domain layer is where the logic lies.
  • The UI links the user to the domain, exposing the features built into that domain.
  • The data layer should be an implementation detail that the domain blindly uses.
  • The data layer contains the code that knows where the data is stored, which should be irrelevant to the domain, but the domain directly depends on it.

The solution to break the tight coupling between the domain and the data persistence implementations is to create an additional abstract layer, as shown in the following diagram:

Figure 14.6: Replacing the data...

Sharing the model

We have explored strict layering and how to apply the DIP, but we still have multiple models. An alternative to copying models from one layer to another is to share a model between multiple layers, generally as an assembly. Visually, it looks like this:

Figure 14.9: Sharing a model between all three layers

Everything has pros and cons, so no matter how much time this might save you at first, it will come back to haunt you and become a pain point later as the project advances and becomes more complex.

Suppose you feel that sharing a model is worth it for your application. In that case, I recommend using view models or DTOs at the presentation level to control and keep the input and output of your application loosely coupled from your model. This way of shielding your lower layers can be represented as follows:

Figure 14.10: Sharing a model between the domain and data layers

By doing that, you will save some time initially by sharing your...

Clean Architecture

Now that we’ve covered many layering approaches, it is time to combine them into Clean Architecture. Clean Architecture is an evolution of layering, a way of organizing the relationships between the layers, similar to what we just built.

Instead of presentation, domain, and data (or persistence), Clean Architecture suggests UI, Core, and Infrastructure.

As we saw previously, we can design a layer containing abstractions or implementations. When implementations depend only on abstractions, that inverts dependency flow. Clean Architecture emphasizes such layers but with its own guidance about organizing them.

We also explored the theoretical concept of breaking layers into smaller ones (or multiple projects), thus creating “fractured layers” that are easier to port and reuse. Clean Architecture leverages that concept at the infrastructure layer level.

There are probably as many points of view and variants of this as there are...

Implementing layering in real life

Now that we covered all of this, it is important to note that on the one hand, there is the theory, and on the other, life is hitting you in the face. Suppose you are working in a big enterprise. In that case, chances are your employer can pour hundreds of thousands or even millions of dollars into a feature to run experiments, spend months designing every little piece, and ensure everything is perfect. Even then, is achieving perfection even possible? Probably not.

For companies that don’t have that type of capital, you must build entire products for a few thousand dollars sometimes because they are not trying to resell them but just need that tool built. That is where your architectural skills come in handy. How do you design the least bad product in a maintainable fashion while meeting stakeholders’ expectations? The most important part of the answer is to set expectations upfront. Moreover, never forget that someone needs to...

Summary

Layering is one of the most used architectural techniques when it comes to designing applications. An application is often split into multiple different layers, each managing a single responsibility. The three most popular layers are presentation, domain, and data. You are not limited to three layers; you can split each into smaller layers (or smaller pieces inside the same conceptual layer), leading to composable, manageable, and maintainable applications.

Moreover, you can create abstraction layers to invert the flow of dependency and separate interfaces from implementations, as we saw in the Abstract layers section. You can persist the domain entities directly or create an independent model for the data layer. You can also use an anemic model (no logic or method) or a rich model (packed with entity-related logic). You can share that model between multiple layers or have each layer possess its own.

Out of layering was born Clean Architecture, which guides the organization...

Questions

Let’s take a look at a few practice questions:

  1. When creating a layered application, is it true that we must have presentation, domain, and data layers?
  2. Is a rich domain model better than an anemic domain model?
  3. Does EF Core implement the Repository and Unit of Work patterns?
  4. Do we need to use an ORM in the data layer?
  5. Can a layer in Clean Architecture access any inward layers?

Further reading

Here are a few links to help you build on what we learned in this chapter:

  • Dapper is a simple yet powerful ORM for .NET, made by the people of Stack Overflow. If you like writing SQL, but don’t like mapping data to objects, this ORM might be for you: https://adpg.link/pTYs.
  • An article that I wrote in 2017 about the Repository pattern; that is, Design Patterns: ASP.NET Core Web API, services, and repositories | Part 5: Repositories, the ClanRepository, and integration testing : https://adpg.link/D53Z.
  • Entity Framework Core – Using Transactions: https://adpg.link/gxwD.

Here are resources about Clean Architecture:

Answers

  1. No, you can have as many layers as you need and name and organize them as you want.
  2. No, both have their place, their pros, and their cons.
  3. Yes. A DbContext is an implementation of the Unit of Work pattern. DbSet<T> is an implementation of the Repository pattern.
  4. No, you can query any system in any way you want. For example, you could use ADO.NET to query a relational database manually and create the objects using data from a DataReader, track changes using a DataSet, or do anything else that fits your needs. Nonetheless, ORMs can be very convenient.
  5. Yes. A layer can never access outward layers, only inward ones.

Learn more on Discord

To join the Discord community for this book – where you can share feedback, ask questions to the author, and learn about new releases – follow the QR code below:

https://packt.link/ArchitectingASPNETCoreApps3e

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Architecting ASP.NET Core Applications - Third Edition
Published in: Mar 2024Publisher: PacktISBN-13: 9781805123385
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime

Author (1)

author image
Carl-Hugo Marcotte

Carl-Hugo Marcotte is a software craftsman who has developed digital products professionally since 2005, while his coding journey started around 1989 for fun. He has a bachelor's degree in computer science. He has acquired a solid background in software architecture and expertise in ASP.NET Core through creating a wide range of web and cloud applications, from custom e-commerce websites to enterprise applications. He served many customers as an independent consultant, taught programming, and is now a Principal Architect at Export Development Canada. Passionate about C#, ASP.NET Core, AI, automation, and Cloud computing, he fosters collaboration and the open-source ethos, sharing his expertise with the tech community.
Read more about Carl-Hugo Marcotte