Comments

Layered Architecture in ASP.NET Core Applications

One of the viewers of my YouTube channel asked me an interesting question. He mentioned in a typical layered architecture, he sees ASP.NET MVC building blocks (Controller, View, and Model) as part of the presentation layer. These days, however, a lot of modern applications are built with Angular/React on the client and ASP.NET Core (Web API) on the server. So, what is the presentation layer in this kind of architecture? Let’s see!

With this stack, we have the following layers:

  • Presentation
  • Service
  • Business Logic/Application Core
  • Data Access/Persistence

Presentation Layer

Your Angular components, their templates, and the models you define in your Angular app are all presentation layer artifacts.

Service Layer

The confusing thing about this layer is that the term “service” is overloaded and it means different things to different people. In the context of a layered architecture, it wraps an application and exposes the application functionality in terms of a simple API that the user interface can talk to. This is the classic definition. Think of it as the glue between the presentation and business logic layers.

Now, in our modern stack, our logical service layer is physically composed of two parts: one part is on the client (Angular HTTP services) and the other part is on the server (ASP.NET Core controllers). These Angular services and ASP.NET Core controllers are very cohesive. The methods on these services (eg CourseService.getCourses()) talk directly to the endpoints exposed by your ASP.NET Core controllers.

Business Logic Layer

In your ASP.NET Core controllers, you often use repository interfaces (ICourseRepository), domain classes (Course) and services (PhotoService). All these are part of the business logic layer. They represent the core of an application irrespective of any presentation or persistence frameworks.

Note that here I’m talking about repository interfaces and not their implementations. These implementations are part of the data access/persistence layer.

Also, note that the services we have here are responsible for orchestration. For example, when adding a photo to a course, first, you need to store that photo in the file system (or some other kind of storage), and then you need to add it to the database (using a repository interface). Here is an example:

// Store the file first 
var uploadsPath = Path.Combine(host.WebRoot, "uploads");
if (!Directory.Exists(uploadsPath))
    Directory.CreateDirectory(uploadsPath);

var fileName = Guid.NewGuid().ToString() + Path.GetExtension(file.FileName);
var filePath = Path.Combine(uploadsPath, fileName);

using (var stream = new FileStream(filePath, FileMode.Create))
{  
    file.Copyto(stream);
}

// Add a record to the database
var photo = new Photo { FileName = fileName };
repository.Add(photo);
unitOfWork.Complete(); 

You wouldn’t write all this logic inside an ASP.NET Core Controller. Imagine, tomorrow you decide to use a different framework. You want to re-use as much code as possible. By encapsulating this code in a service (PhotoService.AddPhoto()), you can switch from ASP.NET Core to a different framework with less effort.

But wait for a second…

Now, that strongly-opinionated developer comes and says: “But who does replace ASP.NET Core with something else? How often does that happen?” Let’s say never! By moving all this logic from a controller into a service, you put the responsibility where it really belongs. The result is cleaner, slimmer, easier to read and easier to test controllers.

Imagine a restaurant where the chef does it all. He’s at the door, welcoming guests, giving them a table, taking their order, then going in the kitchen, chopping the vegetables, cooking, washing the dishes, then coming out and giving the bill to the guests. Would you go to that restaurant? I hope not!

In a good and organized restaurant, there are a few people each focusing on only one job. The waiters/waitresses are purely responsible for welcoming the guests and giving them the bill. The chef is purely responsible for cooking. He or she doesn’t wash the dishes! By the same token, you should have classes that do only one thing and do it well. This is what we call separation of concerns. You should put the responsibility where it really belongs, even if you’re never going to change the presentation or persistence framework of your application.

So, once again, all your domain classes (Course), repository interfaces (ICourseRepository) and application services (PhotoService) are part of the business logic layer. They represent the core of your application completely decoupled from any presentation and persistence frameworks. This is what Uncle Bob defines as Clean Architecture.

Data Access Layer

This layer is all about persistence. Here we have implementations tightly coupled to Entity Framework (or other frameworks) for persisting and retrieving data. If you’re using Entity Framework, your DbContext belongs in this layer. So do UnitofWork and Repository implementations.

Splitting a Project

Now, a common (and bad) practice I’ve seen some developers do, is that they blindly split an ASP.NET project into multiple class libraries, one for each layer. And with this, they assume just because they have a class library called MyProject.BLL or MyProject.DAL, they have properly layered their application. But that’s not necessarily right.

What matters is the direction of dependency and coupling between classes, not folders or projects. You can easily organize your classes into folders and projects but these classes can be poorly coupled to each other, which results in spaghetti architecture. Read my blog post on the topic:

Should you split your ASP.NET MVC/Core projects?

 

If you learned something from this post, please share it and drop your comments/questions below.

Hi, my name is Mosh Hamedani and I am the author of several best-selling courses on Udemy and Pluralsight with more than 130,000 students in 196 countries. You can see the list of all my web and mobile development courses on this website.
Tags: , , , , ,
Comments

Should you split your ASP.NET MVC project into multiple projects?

“Should I split my ASP.NET MVC project into multiple projects?” That’s a question that I get a lot! Almost every week! The short answer is: NO!

I’m not entirely sure how this trend started but I’ve seen some developers split an ASP.NET MVC project into multiple projects: a web project containing the presentation logic, plus two additional class libraries, often named [MyProject].BLL and [MyProject].DLL.

Tiers?

Also, it’s often incorrectly assumed that this structure makes an application multi-tier or 3-tier. What is a multi-tier application? It’s an application whose parts are physically distributed to different computers in a network. Web applications are often inherently multi-tired. In a web application we often have the following tiers:

  1. Client/Presentation Tier: That’s the piece running inside the user’s browser.
  2. Middle/Application/Logic Tier: That’s the part built with ASP.NET MVC (or other similar server-side frameworks) running in a web server.
  3. Data Tier: That’s the database, file system or any other kind of storage.

When we’re talking about ASP.NET MVC, we’re only talking about the application or middle tier. Separating an ASP.NET MVC project into three projects does not result in addition of new tiers in your architecture. You don’t deploy the DAL class library to a different computer! Most of the time (if not always) all these 3 projects (Web, BLL and DAL) are compiled and deployed in the same process on one machine; that is your web server. So, when someone visits your web site, these three DLLs are loaded inside a process (or more accurately an AppDomain) managed by IIS.

Layers vs Tiers

Layers and tiers are used interchangeably by some but they are fundamentally different. Layers are about logical separation, tiers are about physical separation: distributing pieces of a software application to different computers.

Layer is something conceptual in a developer’s head. A class library is not a layer, neither is a folder. You can put classes in a folder or a class library that belong to different layers and be dependent upon each other. This is a sign of bad architecture and coupling. Putting these classes under a folder or a class library like BLL and DAL does not immediately result in software with clean architecture and good separation of concerns.

Despite that, my argument is that these folders (BLL and DAL) can and should reside in the main web project and moving them into a separate class library does not add any values. It doesn’t magically create layers in your applications.

There are 2 cases for splitting a project into smaller projects: reusability and independently deploying those projects.

Reusability

One reason for separating a project into multiple class libraries is re-usability. I’ve yet to see the BLL or DAL part of a web application re-used in another application. This is what text books from 90s used to tell us! But most if not all modern applications are too specific and even in the same enterprise I’ve never seen the same BLL or DAL parts re-used across multiple applications. Most of the time what you have in those class libraries is purely to serve what the user sees in that particular application, and it’s not something that can be easily re-used (if at all).

Deployability

Another reason for separating a project into multiple class libraries is about deployability. If you want to independently version and deploy these pieces, it does makes sense to go down this path. But this is often a use case for frameworks not enterprise applications. Entity Framework is a good example. It’s composed of multiple assemblies each focusing on different areas of functionality. We have one core assembly which includes the main artefacts, we have another assembly for talking to a SQL Server database, another one for SQLite and so on. With this modular architecture, we can reference and download only the parts that we need.

Imagine if Entity Framework was only one assembly! It would be one gigantic assembly with lots of code that we won’t need. Also, every time the support team added a new feature or fixed a bug, the entire monolithic assembly would have to be compiled and deployed. This would make this assembly very fragile. If we’re using Entity Framework on top of SQL Server, why should an upgrade because of a bug fix for SQLite impact our application? It shouldn’t! That’s why it’s designed in a modular way.

In most web applications out there, we version and deploy all these assemblies (Web, BLL and DAL) together. So, separating a project into 3 projects does not add any values.

Use Cases for Physical Separation

So, when do you actually need to physically separate a project into multiple projects? Here are a couple of scenarios:

1- Multiple presentation layers: Let’s say you’ve built an order processing application. This application is a desktop application used by staff at your organization. You decide to build a web interface for this application so the staff can access it remotely. You want to re-use the existing business logic and data access components. As I explained earlier, one reason for physical separation is re-usability. So, in this case, you need to physically separate this project into three projects:

  • OrderProcessing.Core (contains both the BLL and DAL)
  • OrderProcessing.Web
  • OrderProcessing.Desktop

Note that even here I don’t have two projects (BLL and DAL). I have one project, OrderProcessing.Core, that encapsulates both the business and data access logic for our order processing application.

So, why didn’t I separate this project into two separate projects (BLL and DAL)? Because the whole purpose of this DAL is to provide persistence for what we have in BLL. It’s very unlikely that it’ll be used on its own in another project.

Also, following the dependency inversion principle of object-oriented design, the dependency should be from DAL to BLL, not the other way around. So, this means, everywhere you reference the DAL assembly, you should also reference the BLL assembly. In other words, they’re highly cohesive and inseparable. When you separate things that are cohesive, you run into issues later down the track.

2- Multiple applications under a single portal: Another use case that one of the readers suggested is where you have multiple small applications that are hosted in a single portal. So, from the end user’s point of view these applications are not separate; they are all different domains of the same application. But from development point of view, each application is independent from the others. Each application can have its own persistence store; one can use Excel, another can use SQL Server, and the other can use Oracle.

In this scenario, it’s likely that these applications are developed by different developers/teams. They’re often independently developed, version and deployed, hence the second reason for physical separation.

For this scenario, we could have a solution with the following projects:

  • OrderProcessing.Core (a class library)
  • Shipping.Core
  • CustomerSupport.Core
  • MainPortal (an ASP.NET MVC project)

Once again, you don’t see the BLL/DAL separation here. Each class library (eg OrderProcessing.Core) includes both the business and data access logic for its own domain.

The Bottom Line

Here are a few things I hope you take away from this article:

  • Layers are not tiers.
  • Tiers are about physical distribution of software on different computers.
  • Layers are conceptual. They don’t have a physical representation in code. Having a folder or an assembly called BLL or DAL doesn’t mean you have properly layered your application, neither does it mean you have improved maintainability.
  • Maintainability is about clean code, small methods, small classes each having a single responsibility and limited coupling between these classes. Splitting a project with with fat classes and fat methods into BLL/DAL projects doesn’t improve the maintainability of your software.
  • Assemblies are units of versioning and deployment.
  • Split a project into multiple projects if you want to re-use certain parts of that in other projects, or if you want to independently version and deploy each project.

 

As always, keep it simple!

If you enjoyed this post, please share it with your friends.

Hi, my name is Mosh Hamedani and I am the author of several best-selling courses on Udemy and Pluralsight with more than 130,000 students in 196 countries. You can see the list of all my web and mobile development courses on this website.
Tags: , , ,
Comments

Update on my Pluralsight course

I’ve been getting a lot of emails lately, almost on a daily basis, people asking me when my Pluralsight course (Building a Real-world App with ASP.NET MVC) is going to get published and how it is different from my upcoming ASP.NET MVC course on Udemy.

So, I’m going to answer these two questions in this post.

Udemy course

This course will teach you the fundamentals of building web apps with ASP.NET MVC 5. I’m aiming to publish it in 2 weeks or less. Here is a sneak peak of what you’re going to get.

Is this the same as the Pluralsight course? Yes and no. There are some overlaps, but they have differences. In the Pluralsight course, I don’t really teach much of the ASP.NET MVC framework. I’m assuming you have some basic familiarity and want to learn how to build a real-world app end to end.

In the Udemy course, I assume you know nothing about ASP.NET MVC and I teach you all the details step-by-step.

And here is more about the Pluralsight course.

 

Pluralsight course

This course is about 15 hours long, distributed over 3 parts. Almost 95% of the course is reviewed and approved by Pluralsight and we’re aiming to finish it off in less than 2 weeks. But I can’t promise anything because once I fully hand it off to Pluralsight, it’s up to them to decide when they’ll publish it, but I can’t think of a reason why they would want to hold on to that.

By the way, I decided to rename the course from “Building a Real-world App with ASP.NET MVC” to “Become a Full-stack .NET Developer“, because I realized that is really the core of what I teach in this course. It covers a wide range of front-end and back-end skills.

The application I’ve built over these three parts is a simplified social networking app for live gigs. Artists can sign up and list their upcoming gigs. Users can follow artists and get upcoming gigs in their gig feed. If a gig is updated or removed, they’ll receive a notification, similar to Facebook notifications.

Here are more details about each part.

Part 1: Fundamentals

Part 1 is for junior developers who have basic familiarity with ASP.NET MVC and Entity Framework. This is mostly for people who know a little bit of these technologies but don’t know how to put them together and build a real-world application. I’ve received tons of emails from students telling me they don’t know how to start from the requirements document, how to go from one step to the next, how to version their code, etc. So, that’s the essence of this part.

I’ll also talk about security, usability and building beautiful user interfaces using HTML and CSS.

Part 2: Advanced Concepts

Part 2 is for the intermediate developer and includes more advanced use cases. This is where I’ve implemented the Facebook-like notification system. There is a lot of emphasis on domain modelling and object-oriented design in this part. You’ll also learn about refactoring an anaemic domain model (which is a common issue in design of many applications out there) into a behaviour-rich domain model.

Part 3: Architecture and Unit Testing

Part 3 is what takes you from an intermediate developer to an advanced developer. In this part I talk about

  • Refactoring spaghetti JavaScript code
  • Repository and unit of work patterns
  • Programming against interfaces
  • Dependency injection
  • Clean architecture
  • Unit testing
  • Integration testing

This course is packed with concepts, best practices and keyboard shortcuts and I’m sure you’re going to love it.

Pluralsight’s feedback

This morning I woke up with a sweet email from Pluralsight giving me feedback about my course. I was in bed reading the email with one eye and within a few seconds both my eyes were big open and I couldn’t not smile. So I thought to share the feedback with you.

You are a meticulous coder! The spacing, alignment, various conventions, even alphabetical order of things–all awesome

Nice sample app. It’s simple enough to be approachable, but still robust enough to show important concepts, and it feels like a real-world app that I might build.

Clean, crisp audio, good volume. Nice work on recording/editing.

I like your approach of implementing things in an “ugly” way, then showing how to make them better. I think this is a great way to learn; it’s much more effective than showing only the “correct” way up front.

You did a nice job talking through the keyboard shortcuts you were using throughout the demos. Very helpful.

Loved your story about John throwing code wherever with a 5-second approach, then realizing it’s a mess, then implementing with a shiny new framework. I can’t tell you how often I’ve seen this happen!!!

I like that you acknowledged that some developers find testing to be painful and time-consuming. I think this gives you credibility, and shows that you aren’t selling some unrealistic “rainbows and butterflies” view on testing.

Great explanations of IIFE/revealing module pattern.

As much as you’ve been excited to watch this course, I’ve been excited to share all this with you and can’t wait until it goes live. So, if you’ve not joined my mailing list, be sure to join now and I’ll send out an announcement once the course is live.

Hi, my name is Mosh Hamedani and I am the author of several best-selling courses on Udemy and Pluralsight with more than 130,000 students in 196 countries. You can see the list of all my web and mobile development courses on this website.
Tags: , ,
%d bloggers like this: