Monday, May 3, 2010

Layered architecture for ASP.NET applications

This is the first post in a series of discussion on using layered architecture in ASP.NET applications. I will start with the basics and try to elaborate concepts gradually so as to help developers who have just begun to understand the concept of layers in an application.

For quite a while, a tiered approach towards developing an application has been in the buzz. We hear people talking 2-tier, 3-tier, n-tier applications! What is a “tier” here? It means a layer. When a civil engineer is designing a building, he works on a blueprint of the building. In the blueprint, there is a clearly defined sketch of each part, viz. the base, the pillars, the first floor, the subsequent floors, electrical plans may be!  How the base is to be built and pillars placed so that the floors will be strong is very important consideration. The same applies to developing software applications. We are talking specifically about web applications here to be developed in ASP.NET and we will choose C# as the language for our examples.

A web application should be developed in layers. Each layer should be defined precisely to meet a distinct purpose. The interactions between each layer should be well thought of. In short,

  • Each layer should be designed for a specific purpose and a distinct objective.
  • Each layer should have a unique responsibility and hence not mess up with any other layer’s duties.
  • The interaction between the layers should be well defined. This is very important, failing which layered architecture will not only be an overhead but become clumsy and a havoc to maintain.
2-tier architecture

Consider a very simple ASP.NET application where there are aspx pages directly interacting with the database. For example, the application has an aspx page with a grid whose datasource is set to a dataset and the code for connecting the dataset and populating it is written in the code behind file. The aspx file and its code-behind file contains the content to be displayed on the browser (the web controls), business logic and code for interaction with database.

Here is an example:

Products.aspx
<html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
            <div>
                <asp:GridView ID="GridView1" runat="server">
                </asp:GridView>
            </div>
        </form>
    </body>
</html>
Products.aspx.cs
using System;
using System.Data;
using System.Data.SqlClient;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Configuration;
public partial class Products : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ToString());
        DataSet dsProducts = new DataSet();
        SqlDataAdapter adapter = new SqlDataAdapter("SELECT ProductID,ProductName,UnitPrice FROM Products", conn);
        adapter.Fill(dsProducts);
        GridView1.DataSource = dsProducts;
        GridView1.DataBind();
    }
}
To explain the code in short, all we are doing is to execute a SELECT query against Products table in the Northwind database, and then bind a grid to the dataset. The page when loaded will display all products in the grid.

In this architecture, often to make code less cumbersome and keep things short and clean, you may also opt to write stored procedures that performs multiple tasks at the database end. Now, these stored procedures may also very often include some business logic code. For example, you may maintain transactions within a stored procedure and hence end up implementing a part of application’s business logic in the stored procedure or using constraints and triggers in the database. Here what we have is:

  • Application layer – the aspx page and its code- behind forms the application layer that delivers the presentation of data to the user and also contains the business logic.
  • Data access layer – the underlying database acts as the data access layer here. This means the entire database engine, including the database objects (e.g. tables, views) and the manipulating code (e.g. stored procedures).
It means you are using 2-tier architecture. Many of us think that because .aspx files have a separate code behind files, that counts as two different layers and hence ASP.NET applications are by default 3-tiered. Sorry, that’s not the way we can look at it. There is absolutely no difference in writing all the code behind part in the aspx files itself or separating it into a separate code behind file. Code-behind files only provide you a neater way to maintain your code and make sense out of it. Code-behind files do not contribute as a separate layer, unless you want to believe it that way.

3-tier architecture

In the above architecture, we found that although there was an attempt to make a distinction between the two layers, we could often end up having a part of our business logic implemented at the data access layer. To solve this problem, we can introduce a separate layer in between called “Business Logic Layer” where we will implement all business logic of the application and that will interact with the data access layer. This way, the data access layer keeps itself limited to handling database interaction and providing data to or updating data from the business logic layer.

We will see what I mean by a separate business logic layer. But before that, let us restructure the example code of 2-tier architecture from above. What we will do is put the database interaction code into a separate class. This class will be the actual “data access layer” for us and will be mainly and only used for database interaction purpose. The new class will be as:

ProductDataAccessLayer.cs

Our code-behind file will now look like:

Products.aspx.cs

Looks better? Remember, we still have only two layers: the ProductDataAccessLayer is just a cleanly maintained data access layer. The aspx file with its code behind forms the presentation layer.

Now lets say the unit price that is displayed for each product is without the VAT at present. The actual unit price should be inclusive of 12.5% VAT for each item. It would be a bad idea to place the logic into the data access layer since this class is meant to perform actions like select, insert, update and delete etc. And even if we put it there hardcoded, what if the government decides to change VAT to 13% percent tomorrow? What is the best solution then? Remember, we know that touching the data access layer for business logic changes is a bad idea, and we also know that the aspx and code-behind is best for presentation purpose.

Let us add a new layer, the business logic layer. So, here is the example code updated

This is our old data access layer:

ProductDataAccessLayer.cs

I will add a new class "ProductBusinessLogicLayer".

ProductBusinessLogicLayer.cs

And our aspx code behind will change to:

Products.aspx.cs

Notice that the newly introduced class “ProductBusinessLogicLayer” acts as an interface between the presentation and data access layer and has the business logic code for VAT calculation implemented. Any changes in business logic tomorrow will affect only this class. Yu do not have to be concerned about the data layer or the presentation layer while making changes to the business logic.

What we get is a clear separation of business logic and data interaction. Your application just became easily maintainable and extendable!

What we have here is:
  • Application layer – the aspx page and its code- behind forms the application layer that delivers the presentation of data to the user.
  • Business logic layer – the business logic part is moved into an intermediate layer.
  • Data access layer – the data access layer with the underlying database engine forms the data access layer.
So you have 3-tier architecture.

I will talk about implementing 3-tier architecture in detail in the next post, and also look at various methods to implement a 3-tier or n-tier architecture, with examples. Sometime later, we will also talk about the MVC architecture.

1 comments:

nice article...explained in simple language...Thanks :-)