Monday 22 April 2013

Understanding Multilayered Architecture in .Net


Understanding Multilayered Architecture in .Net


This article focuses on understanding a basic multilayered architecture in C#.Net.

Contents [hide]

Introduction

The article starts with introduction to one tier, two tier and n-tier architectures, their pros and cons, and later describes how we can achieve a simple basic multilayered architecture in .Net.
My effort in this article would be to focus on next level programming in .Net for developing an enterprise application.

Layered Architecture

When the different components in a system are organized systematically we call it a system architecture. The architecture is the enterprise-scale division of a system into layers or tiers, each having responsibility for a major part of the system and with as little direct influence on other layers.

One, two, three and n-tier applications

There are plenty of ways where a system can be split into no. of logical tiers.

One-tier applications

Single-tier applications are basically simple standalone programs.
It's not necessary to take network communication and the risk of network failure into consideration in these type of cases as they do not have the network access.
Since all the data resides within the same application, so these programs do not focus on synchronization of data. When separating the tiers physically the application get slower due to the fact that communication over network will result in a loss of performance, therefore one-tier applications certainly have high performance.

Two-tier applications

A two-tier application, in comparison to the one-tier application as described, does not combine all functions into a single process but separate different functions. For example a chat application. This kind of application contains two separated tiers, client and a server.
The client has the responsibility of capturing user input and displaying the actual messages. The server is responsible of the communication between the people that uses the chat client.

Three-tier applications

A three-tier application, adds another tier to the previous mentioned chat application, this could be in the form of a database. One could think of a three-tier application as a dynamic web application, which has a user interface, business logic, services and a database each placed in different tiers, as illustrated in Figure 1. As mentioned in the previous section a two-tier architecture separates the user interface from the business logic, in the same way the three tier architecture separates the database from the business logic.

Figure 1: Three-tier application

Three-tier application

N-tier applications

A logical n-tier application is an application where all logical parts are separated into discrete classes. In a typical business application, this generally involves a presentation layer, business logic layer and a dataaccess layer. This separation makes the application easier to maintain. The advantages of this architecture are that all business rules are centralized which make them easy to create, use and re-use. The data access is also centralized, which has the same advantage as the centralization of the business rules. Centralizing the data access routines are also good when it comes to maintenance since changes only has to be implemented at one location. There are really not that many disadvantages of this kind of architecture, however, it takes a bit longer to get up and running since several separate components has to be developed, which also might make the code a bit more complicated to grasp for less experienced developers.

A Practical Approach

Let's start developing a simple multilayered architecture in .Net, I take c# as my programming language, however programming language is not a bar at all , one can choose the same as per comfort of programming. The architecture which we are to implement has the following design as mentioned in Figure 2.We will start creating the architecture for a web application , later it could be converted into a windows application too.
We will make use of class libraries to physically separate our layers. There for one Web Application/Project, one Business logic layer class library , one Data access layer class library and one Common layer class library can be included in the solution.
Lets follow the implementation Step by Step.

Step 1: Add a Web Project (Presentation layer).
Open your Visual Studio and add a simple website to the solution, name it Presentation Layer.

Your Development Environment may look like the following.

Our Presentation Layer is the Web application, that will be exposed to the end user,
The Web application includes Web Forms i.e. aspx pages, User Controls i.e. Ascx pages, Scripts (client side java scripts),Styles (css and custom styles for styling the page),Master Page(.master extension, for providing common functionality to group of desired pages, Configuration Files like web.config and app.config etc.).
Let's setup our next projects and define them in separate layers, Add three folders to your solution, Folders named, BusinessLogicLayer, DataAccessLayer and CommonLayer. Your solution will look like as below.

Step 2. Add a Business Logic layer, Data Access Layer and Common Layer :
Right click the Business Logic Layer folder and add a c# class library project to it, call it BLL.csproj.

Doing this will add a c# class library project to our solution in the Businee Logic Layer Folder.
Add two more projects to Common Layer and DataAccessLayer folder respectively and call them Common.csproj and DAL.csproj.
The Data Access Layer Project Contains the entities classes and objects to communicate with database, whereas our common project contains properties, helper classes to communicate with all the three layers commonly. It contains the objects to be passed to and fro from presentation layer to data access layer commonly, and also acts as a mode of message passing between the layers.
Now our solution would look like as below.

Step 3. Create a database with a sample table and put some default values in it, for example I have created a database named "EkuBase" and created a siple Student table with following fields: StudentIdNameEmailAddress,AgeCountry. The Create script of the table is as follows.
01.USE [EkuBase]
02.GO
03./****** Object:  Table [dbo].[Student]    Script Date: 12/24/2011 14:53:14 ******/
04.SET ANSI_NULLS ON
05.GO
06.SET QUOTED_IDENTIFIER ON
07.GO
08.CREATE TABLE [dbo].[Student](
09.[StudentID] [intNOT NULL,
10.[Name] [nvarchar](50) NULL,
11.[Email] [nvarchar](50) NULL,
12.[Address] [nvarchar](50) NULL,
13.[Age] [intNULL,
14.[Country] [nvarchar](50) NULL,
15.CONSTRAINT [PK_Student] PRIMARY KEY CLUSTERED
16.(
17.[StudentID] ASC
18.)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ONON [PRIMARY]
19.ON [PRIMARY]
20.GO
Therefore making studentid as primary key.
Step 4. Lets add classes to our projetcs. Add StudentBLL.cs, StudentDAL.cs, StudentEntity.cs to BLL, DAl and Common Layer respectively. Make sure you qualify them with logical namespaces, so that it's easy to recognize and use them.

Listing 1: BLL

01.using System;
02.using System.Collections.Generic;
03.using System.Linq;
04.using System.Text;
05.namespace BLL
06.{
07.public class StudentBLL
08.{
09.}
10.}

Listing 2: DAL

01.using System;
02.using System.Collections.Generic;
03.using System.Linq;
04.using System.Text;
05.namespace DAL
06.{
07.public class StudentDAL
08.{
09.}
10.}

Listing 3: Common

01.using System;
02.using System.Collections.Generic;
03.using System.Linq;
04.using System.Text;
05.namespace Common
06.{
07.public class StudentEntity
08.{
09.}
10.}
Step 5. Add Connection String in web.config and a Helper class to DAL to interact with DataBase. In my case I am using SQL helper for ease.

Listing 4: Web.Config

1.<connectionStrings>
2.<add name="Connections" connectionString="DataSource=69B5ZR1\SQLEXPRESS;Initial
3.Catalog=EkuBase;Persist Security Info=True;UserID=akhil;Password=akhil"
4.providerName="System.Data.SqlClient"/>
5.</connectionStrings>
Define the Connection String in your Sql Helper so that you don't have to again and again create a connection and pass it to your method when you interact with database.
1.public static readonly string CONN_STRING =
2.ConfigurationManager.ConnectionStrings["Connections"].ConnectionString;
Add a reference to System.Configuration to DAL project before reading the above connection string.
Step 6. Configure the solution and add dlls to dependent layers,
Since we need to separate the business logic, presentation and data access, and we do not want presentation layer to directly interact with database nor the business logic, we add reference of business logic layer to our presentation layer and data access layer to the business logic layer and common layer to all the three layers. To achieve the same add a common DLL folder to the physical location of the Solution and give build path of all the three class projects to that DLL folder, doing this we can directly get access to DLL's of all the layers to the layers needed that DLL. We'll get the dlls in that folder once we complete our project.


Do this for DAL and Common Layer as shown in Figure 8. After compiling all the projects we get dlls in the DLL folder created.

Now add references to Common.dll, BLL.dll to Presentation Layer, Common.dll,DAL.dll to BLL Layer, Common.dll to DAL layer and compile your solution.
Now the code of BLL is accessible to Presentation Layer,and DAL is accessible to BLL, and Common is accessible to all three layers.
Step 7. Write methods to get the flow.
Now we need to write some code to our layers to get the feel of flow between all the layers, Let's create a scenario. Suppose we need to get the details of all the students whose student id is less than 5.For that add some sample data to your Student table, about 7 rows would work(Figure 11),and add a GridView to Default.aspx in presentation layer to show the data.

Listing 5: Default.aspx

01.<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
02.CodeFile="Default.aspx.cs" Inherits="_Default" %>
03.<asp:Content ID="HeaderContent" runat="server"ContentPlaceHolderID="HeadContent">
04.</asp:Content>
05.<asp:Content ID="BodyContent" runat="server"ContentPlaceHolderID="MainContent">
06.<h2>
07.Welcome to ASP.NET!
08.</h2>
09.<p>
10.To learn more about ASP.NET visit <ahref="http://www.asp.net" title="ASP.NET Website">www.asp.net</a>.
11.</p>
12.<p>
13.You can also find <ahref="http://go.microsoft.com/fwlink/?LinkID=152368&;clcid=0x409"
14.title="MSDN ASP.NET Docs">documentation on ASP.NET at MSDN</a>.
15.</p>
16.<div>
17.<asp:GridView runat ="server" ID="grdStudent"></asp:GridView>
18.</div>
19.<div>
20.<asp:Label runat="server" ID="lblError" Font-Bold=true ForeColor=red ></asp:Label>
21.</div>
22.</asp:Content>
Now decorate your StudentEntity Class in Common layer with following code, to make properties for each column we are going to access from Student table.
01.using System;
02.using System.Collections.Generic;
03.using System.Linq;
04.using System.Text;
05.namespace Common
06.{
07.public class StudentEntity
08.{
09.int studentID;
10.public int StudentID
11.{
12.get return studentID; }
13.set { studentID = value; }
14.}
15.string name;
16.public string Name
17.{
18.get return name; }
19.set { name = value; }
20.}
21.string email;
22.public string Email
23.{
24.get return email; }
25.set { email = value; }
26.}
27.string address;
28.public string Address
29.{
30.get return address; }
31.set { address = value; }
32.}
33.int age;
34.public int Age
35.{
36.get return age; }
37.set { age = value; }
38.}
39.string country;
40.public string Country
41.{
42.get return country; }
43.set { country = value; }
44.}
45.}
46.}
Decorate StudentDAL with following code to call the data from database. We always write data interaction code in this layer only, making it as a protocol.
01.using System;
02.using System.Collections.Generic;
03.using System.Linq;
04.using System.Text;
05.using System.Data;
06.namespace DAL
07.{
08.public class StudentDAL
09.{
10.public DataSet FetchSelectedStudents()
11.{
12.string sqlCommand = "select * from Student where Studentid<5";
13.DataSet dataSet = SqlHelper.ExecuteDataset(SqlHelper.CONN_STRING, CommandType.Text, sqlCommand);
14.return dataSet;
15.}
16.}
17.}
Here we simply make a call to database to get students having id less than 5.
We write following code to BLL class, where we perform validation check for the id whether it is less or greater than 5, and correspondingly throw error is its greater than 5,which we show at our default.aspx page by setting the message to error label text.BLL makes call to DAL to fetch the students, and passes to Presentation Layer, where data is shown in GridView.
01.using System;
02.using System.Collections.Generic;
03.using System.Linq;
04.using System.Text;
05.using DAL;
06.using System.Data;
07.using Common;
08.namespace BLL
09.{
10.public class StudentBLL
11.{
12.public DataTable GetStudentBelow5(StudentEntity student)
13.{
14.StudentDAL studentDAL = new StudentDAL();
15.if (ValidateID(student.StudentID))
16.{
17.returnstudentDAL.FetchSelectedStudents().Tables[0];
18.}
19.return null;
20.}
21.private bool ValidateID(int studentID)
22.{
23.if (studentID > 5)
24.{
25.throw new ApplicationException("Id Should be less than 5");
26.}
27.return true;
28.}
29.}
30.}
In Presentation layer we write code to bind our gridview else show error message in case of error returned from BLL.

Listing 6: Default.aspx.cs

01.using System;
02.using System.Collections.Generic;
03.using System.Linq;
04.using System.Web;
05.using System.Web.UI;
06.using System.Web.UI.WebControls;
07.using System.Data;
08.using BLL;
09.using Common;
10.public partial class _Default : System.Web.UI.Page
11.{
12.protected void Page_Load(object sender, EventArgs e)
13.{
14.StudentBLL studentBLL = new StudentBLL();
15.StudentEntity studentEntity=new StudentEntity();
16.studentEntity.StudentID=6;
17.DataTable dTable = new DataTable();
18.try
19.{
20.dTable = studentBLL.GetStudentBelow5(studentEntity);
21.grdStudent.DataSource = dTable;
22.grdStudent.DataBind();
23.}
24.catch (ApplicationException applicationException)
25.{
26.lblError.Text = applicationException.Message;
27.}
28.}
29.}
In the above code we specify student id as 6 in Student Entity and pass it to BLL, when we run the code we get the following page with our error label set with the error message.

It clearly states that id should be less than 5.Note that we do not get to DAL before the data is validated.
Now change the student id to 5 and see the result. We get the following page.

Thus we get the clear result.
Here we have seen how we communicated through different layers performing different roles to fetch the data.

General advantages of layered applications

There are various advantages of developing applications that are split up into different tiers or layers. Most importantly this form of architecture helps to enforce the principles of high cohesion within system components and low coupling between different components. A system built on these principles will be more robust, easier to adjust, easier to maintain and understand and it allows different software components to be developed in parallel.
The key point is that a system should be split into different smaller parts that are as cohesive and self-governing as possible. Each part has distinct responsibilities and interacts with other parts of the system to accomplish its tasks and responsibilities. This also ensures that the systems can corporate across different platforms and communication protocols and makes it easier to reuse existing solutions to problems often encountered.
All in all these advantages are desirable because they work in the direction of low coupling and high cohesion. The hard part is, however, to implement this in practice and to know when and how it should be implemented. What objects should have responsibility for the different tasks and how do they interact.

No comments:

Post a Comment