There is a misunderstanding that tier and layers are two different names for the same entity. The concept of tier and layers came into being with the need for identifying and segregating different parts of an application into separate connected components. This separation can be at two levels:
In a tier-based architecture, we separate code physically into different assemblies (or a set of assemblies). For example, we may have a single assembly for the web project, and another one for the class project having business code. If we want to deploy our application across multiple servers, spanning different geographical locations, then we need to use an n-tier architecture (which we will study in the coming chapters of this book).
Separating into layers mean that we logically separate the code, but the entire application will be a part of a single physical assembly (or a set of assemblies depending on the compilation model). We may put the code files into separate folders, each having its own namespace for easier code management and readability, but we won't have a separate assembly for each different namespace or part of the code. Also, unlike physical separation, it will not be possible to deploy parts of the application in a distributed manner.
So a "tier" is a unit of deployment, while a "layer" is a logical separation of responsibility within the code. A layer becomes a tier if it can be physically separated from the layers consuming it. Alternatively, a tier is a layer which could be physically separated from the layers consuming it.
If we are using the Visual Studio 2005 Website model, then we may have a set of assemblies for each page/folder, whereas if we use a Web Application Project (WAP) model (similar to the one used in VS 2003) we will have only a single assembly for the entire project.
Let's say we have a simple online guestbook system, which is a web-based application developed in ASP.NET. Here is a simple flowchart in a very basic form:
The user logs on to the website and visits the online guestbook, and clicks on the show all comments button. As a result, the system will show a list of comments to the user. For the same, the system sends a query to the Access DB, which in turn replies with a list of all the comments.
Now, one way to program this system is to create a simple web form with button, with the code to get the comments from the database placed inside the ASPX form (without using any code behind classes). The solution will compile into a single DLL. This inline coding approach will be discussed in the next chapter. Another method is to use code behind classes segregating the ASPX code and the C#/VB.NET code. We can introduce further loose coupling by separating the business logic and data access code into separate class library projects.
For a Windows-based project, also known as a thick-client, an n-tier project would have:
Windows forms (or Windows Presentation Foundations, WPF) as the Presentation layer
C# or VB.NET code handling the business logic as the Business Layer (BL)
Data access code as the Data Access Layer (DAL)
The physical database as the Data Layer (DL)
Data access layer (DAL) is a set of classes used to encapsulate data access methods like CRUD (Create Read Update and Delete) operations as well as any other methods accessing data from a data store (known as Data Layer). DAL's primary job is to communicate with the Data layer, which can be any RDBMS, set of XML files, text files, and so on. The DAL layer should act as a 'dumb layer' which is used directly by the BLL or any other service layer. The DAL layer should not contain any specific logic in its classes, and it should be used like a "utility" or "helper" class to fetch and store data to and from a data store.
Business logic layer (or the BLL) contains the business logic and set of operational rules particular to the application and talks to the data access layer (DAL) to:
fetch data on which it has to apply rules
save updated data after applying rules to it
perform operations and validate data
BLL usually presents the data to the higher Layers (like a GUI layer) after performing business rules on it. This layer may also include error handling, logging, and exception handling strategies, besides encapsulating all the business rules of the project.
UI layer contains the graphical display components and files like ASPX, ASCX, MasterPages, stylesheets and so on. The UI layer usually is the Website or Web Project in the Visual Studio solution for ASP.NET projects.
Most developers confuse the data access code (DAL) as the data layer (DL). The data and data the access layer are different. DAL is the actual code that we use in our applications to connect to a database, and the database itself is actually the data layer (DL).
Here is a sample diagram of how the different layers act:
Now in the diagram, if we separate each of the code layers into its own project and class library, then we will have a 4-tier project: Presentation tier, BL tier, DAL tier and DL tier (the physical database).
But with web based applications, we have a built-in 3-tier architecture by default. The presentation tier is the client-side browser (instead of Windows forms), the code (assuming you have web forms, BL, and DAL in one assembly) is the Application tier, and the physical database is the Data tier.
If we break up the web project so that we have the business logic and data access code in one assembly, and the web forms/
ascx controls and so on in another, we will have a 4-tier architecture. We can go on like this by breaking each component out into its own tier and introducing further loose coupling. We will see more on how to introduce loose coupling in our projects in the later chapters of this book. For the rest of the book, we will be focusing only on thin-client based architectures, that is, web applications in ASP.NET.
We will now see what options we have for how we can break the code into different tier and layers in any Visual Studio web project, and thus define a few models. Here I am assuming that we are breaking the main application into tiers, and not focusing on the database and the presentation (browser) tiers.
ASP.NET Web Project compiling into a DLL in the
/bin folder and under a single namespace:
No. of project files: 1
No of namespaces: 1
There is no separation of presentation, business logic, and data access code layers. Because we will have only one assembly (or set of assemblies) that cannot be distributed independently, this model would be single tier and single layer. We can use this model for very simple projects, on which only one developer is working and where we are sure there are no major scalability or maintainability issues. For example, a personal guestbook system, small 2 or 3 page web applications, or web sites with mostly static content.
Actually if you make an application based on the above model, it will follow a 3-tier architecture 'overall', if we bring the database and the browser as the other tiers and count them inside the application. This is the reason why I mentioned that for the time being we should forget about the external tiers and focus on how to break the monolithic ASP.NET application into further tiers.
ASP.NET Web Project that has two folders:
Code: This folder will have class files containing business logic and data access code under a single namespace, say
Web: This folder will have the user controls, ASPX pages, and other presentation-related code under the namespace, say
Here, as the business logic and data access code are logically separated from the presentation code, we have two layers. However, as all code files would still be compiling into assemblies under a single project's
/bin, we will have only one tier. We can use this model for projects that have little or no business logic but need to access a database for content.
ASP.NET Web Project that has logical separation between presentation, business logic and data access code:
All presentation code will be under the
MyApp.Webnamespace (Layer 1).
Furthermore, the single project can have two folders:
Business (Layer 2): for business logic code, with namespace
DAL (Layer 3): for data access code, with namespace
Note that it is not necessary to have different folders for the logical separation of code; using different namespaces in different code files will also work fine. We can use this model for a medium-to-large web application where we know that many users won't log in simultaneously. For handling a large number of users, the application needs to be scalable, and to do this we might need to separate BL and DAL code into their own physical assemblies.
Here we create two projects, one normal web project for UI code, and another class library project for the BL and DAL code. This will ensure that even if we change the BL or DAL code, we don't need to recompile the web project as we have separate physical assemblies. This setup is more scalable and maintainable than all previous options. Separating code into different assemblies will involve a slight performance hit, but that is negligible considering the flexibility and maintainability benefits we get by having two tiers.
The solution will have:
ASP.NET Web Project having GUI and presentation code (Tier 1)
A class library project having business logic and data access coding under a single namespace,
MyApp.Code; no separate namespaces for business logic and data access code (Tier 2)
The solution will have:
ASP.NET Web Project having Presentation Layer coding in ASPX and ASCX files, under the namespace,
A class library project having two folders (Tier 2):
If the project is large, with a lot of complicated business logic, then it's more useful to separate the BL and DAL into in their own assemblies so that we can change the BL code without changing the DAL assembly. This makes our application more flexible and loosely-coupled as we can use a different DAL assembly for a different database with the same BL assembly.
The solution will have:
ASP.NET Web Project having Presentation Layer coding in ASPX and ASCX files, under namespace
A class library project having business logic code, with namespace,
A class library project DAL for data access code, with namespace,
Once again, if we also bring the Presentation and Database to be a part of the entire application here, the above 3-tier model would become a 5-tier model!
The above structures and layouts show some of the possible ways we can architect our solutions, and also illustrate the differences between layers and tiers. We can have more tiers (n-tier), and can customize our solution with a mix of tiers and layers, according to the project's needs. There is a common misconception among beginner developers that a 3-tier (or n-tier) architecture is the only best model, and many new developers try to blindly follow this model without even giving a second thought to their actual project's needs. As we go from one tier to n-tier, the code complexity increases, and it is better not to go for an n-tier architecture unless the application demands it. For small projects, we can keep things simple and easy.