Understand 3-Tier Architecture in C#

In this article, we will learn to implement 3-tier architecture in a C# application. 3-tier architecture is a very famous and well known buzzword in the world of software development. If we analyze any traditional project then we will find that most of (at least 60-70%) them have traditional N-tier, basically 3-tier architecture. It does not matter whether it is a web or Windows application, we can implement 3-tier architecture in any type of environment.

Although it is a very well known and common architecture, it's not very clear to beginner developers or those who are very new in project development.

Why 3-Tier Architecture?


Still I can remember that, the first organization in my career was dealing with one small Point of Sales (POS) project. It was a Windows application and there was no layered architecture. We developers started to write all code in the Windows Forms Application. The problem started after a few days. How? When our manager announced that we need to develop one web version of the same product. Again we started to develop web pages from scratch and started to write all code. A total mess.

So, this is the problem and the solution is tierd architecture. If we separate our code by layers then changes in one layer will not affect another very much. Tomorrow if the business demands, we can change the UI very quickly by using existing code.

Difference between tier and layer


It is a confusing question for beginners. A few think that both are the same. But they are not the same. Tier represents multiple hardware boxes. In other words the components are physically separated into multiple machines. But in the case of layers all components are in the same system.

What are the Layers?


Theoretically it is N-tier architecture. So, we can create as many layers as possible but basically people classify code in three categories and put them in three layers. So, for this article we will consider N-tier architecture as 3-tier architecture and try to implement one sample application.

Let's explain each and every layer first.

Presentation Layer/ UI Layer


This is the top-most layer of the application where the user performs their activity. Let's take the example of any application where the user needs to fill up a form. This form is nothing but the Presentation Layer. In Windows applications Windows Forms are the Presentation Layer and in web applications the web form belongs to the Presentation Layer. Basically the user's input validation and rule processing is done in this layer.

Business Layer


This is on top of the Presentation Layer. As the name suggests, most of the business operations are performed here. For example, after collecting form data we want to validate them with our custom business rule. Basically we define classes and business entities in this layer.

Data Access Layer


On top of the Business Logic Layer is the Data Access Layer. It contains methods that help the business layer to connect with the database and perform CRUD operations. Generally all database related code and stuff belongs to the Data Access Layer. Sometimes people use a platform-independent Data Access Layer to fetch data from various database vendors.

Let's Implement

Before starting with an example, one more question needs to be clarified. How will we pass data from one layer to another layer? In other words, in which form is the data passed?


There are many solutions for this problem. For our example, we will pass data using function parameters. In this example, we will implement one small Windows application to fetch data from the database using 3-tier architecture. In this example, we will read data from a single "Person" Table.

Code for Data Access Layer


Let's start from the Data Access Layer; we will create a function to read data from the database. Have a look at the following code.
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Data;  
  4. using System.Data.SqlClient;  
  5. namespace WindowsFormsApplication1.DAL  
  6. {  
  7.     public class PersonDAL  
  8.     {  
  9.         public string ConString = "Data Source=SOURAV-PC\\SQL_INSTANCE;Initial Catalog=test;Integrated Security=True";  
  10.         SqlConnection con = new SqlConnection();  
  11.         DataTable dt = new DataTable();  
  12.         public DataTable Read()  
  13.         {  
  14.             con.ConnectionString = ConString;  
  15.             if (ConnectionState.Closed == con.State)  
  16.                 con.Open();  
  17.             SqlCommand cmd = new SqlCommand("select * from Person",con);  
  18.             try  
  19.             {  
  20.                 SqlDataReader rd = cmd.ExecuteReader();  
  21.                 dt.Load(rd);  
  22.                 return dt;  
  23.             }  
  24.             catch  
  25.             {  
  26.                 throw;  
  27.             }  
  28.         }  
  29.         public DataTable Read(Int16 Id)  
  30.         {  
  31.             con.ConnectionString = ConString;  
  32.             if (ConnectionState.Closed == con.State)  
  33.                 con.Open();  
  34.             SqlCommand cmd = new SqlCommand("select * from Person where ID= "+ Id +"", con);  
  35.             try  
  36.             {  
  37.                 SqlDataReader rd = cmd.ExecuteReader();  
  38.                 dt.Load(rd);  
  39.                 return dt;  
  40.             }  
  41.             catch  
  42.             {  
  43.                 throw;  
  44.             }  
  45.         }  
  46.     }  
  47. } 

We have created two overloadeded functions to read data. One function will not take any arguments and other functions will fetch data using ID.

Create a Business Logic Layer


We will now create a Business Logic Layer to communicate with both the Presentation Layer and Data Access Layer. Here is our code for the Business layer.

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Data;  
  4. using WindowsFormsApplication1.DAL;  
  5. namespace WindowsFormsApplication1.BLL  
  6. {  
  7.     public class PersonBLL  
  8.     {  
  9.         public DataTable GetPersons()  
  10.         {  
  11.             try  
  12.             {  
  13.                 PersonDAL objdal = new PersonDAL();  
  14.                 return objdal.Read();  
  15.             }  
  16.             catch  
  17.             {  
  18.                 throw;  
  19.             }  
  20.         }  
  21.         public DataTable GetPersons(Int16 ID)  
  22.         {  
  23.             try  
  24.             {  
  25.                 PersonDAL objdal = new PersonDAL();  
  26.                 return objdal.Read(ID);  
  27.             }  
  28.             catch  
  29.             {  
  30.                 throw;  
  31.             }  
  32.         }  
  33.     }  
  34. }

Create a Presentation Layer


This is the top-most layer where the user interacts with the system. We will create simple windows as in the following:

Layer1.jpg

The form contains one DataGrid, one TextBox and one Button. In the load event of the form we will pull all data and it will show in the DataGrid. There is another operation, where can the user fetch a specific person by providing the person's ID. Have a look at the following code.

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.ComponentModel;  
  4. using System.Data;  
  5. using System.Drawing;  
  6. using System.Linq;  
  7. using System.Text;  
  8. using System.Threading.Tasks;  
  9. using System.Windows.Forms;  
  10. using WindowsFormsApplication1.BLL;  
  11. namespace WindowsFormsApplication1  
  12. {  
  13.     public partial class Form1 : Form  
  14.     {  
  15.         public Form1()  
  16.         {  
  17.             InitializeComponent();  
  18.         }  
  19.         private void button1_Click(object sender, EventArgs e)  
  20.         {  
  21.             try  
  22.             {  
  23.                 PersonBLL p = new PersonBLL();  
  24.                 this.dataGridView1.DataSource = p.GetPersons(Convert.ToInt16(this.txtID.Text));  
  25.             }  
  26.             catch  
  27.             {  
  28.                 MessageBox.Show("Error Occurred");  
  29.             }  
  30.         }  
  31.         private void Form1_Load(object sender, EventArgs e)  
  32.         {  
  33.             try  
  34.             {  
  35.                 PersonBLL p = new PersonBLL();  
  36.                 this.dataGridView1.DataSource = p.GetPersons();  
  37.             }  
  38.             catch  
  39.             {  
  40.                 MessageBox.Show("Error Occurred");  
  41.             }  
  42.         }  
  43.     }  
  44. }

So, this is the entire project structure:

Layer2.jpg

Here is sample output in the form load event.

Layer3.jpg

If we want to search for a specific person then we need to provide an ID.

Layer4.jpg

Table Structure

Here is our table structure. It contains the three fields ID, name and surname.

Table Name: Person

Layer5.jpg

Conclusion

In this article, we have seen how to implement simple 3-tier architecture in .NET. Hope you have understood the concept. In a future article, we will concentrate more on 3-tier architecture.


Similar Articles