N-Tier Architecture Example

In software engineering, multi-tier architecture (often referred to as n-tier architecture) is a client–server architecture in which the presentation, the application processing, and the data management are logically separate processes. For example, an application that uses middleware to service data requests between a user and a database employs multi-tier architecture. The most widespread use of multi-tier architecture is the three-tier architecture.

N-tier application architecture provides a model for developers to create a flexible and reusable application. By breaking up an application into tiers, developers only have to modify or add a specific layer, rather than have to rewrite the entire application over. There should be a presentation tier, a business or data access tier, and a data tier.

The concepts of layer and tier are often used interchangeably. However, one fairly common point of view is that there is indeed a difference, and that a layer is a logical structuring mechanism for the elements that make up the software solution, while a tier is a physical structuring mechanism for the system infrastructure. For the purposes of this article I will be discussing the following architecture. This will be the foundation of which follow up post will be coming over the next few weeks so I hope you stay tuned.

n-tier architecture

Open up Visual Studio and create a new solution named RadDevExamples. From here create four class libraries with the solution and name them BLL, DAL, Model, and Utilities. Finally add a new ASP.NET empty web site. Your solution should look like this:

radical developement solution example

Model Layer

Create a new class named Employee. This class will reflect the attributes of the employee as well as the desired constructors.

public sealed class Employee
{
private Guid _employeeId;

public Guid EmployeeId
{
get { return _employeeId; }
set { _employeeId = value; }
}

private string _lastName;

public string LastName
{
get { return _lastName; }
set { _lastName = value; }
}

private string _firstName;

public string FirstName
{
get { return _firstName; }
set { _firstName = value; }
}

public Employee()
{
_employeeId = Guid.Empty;
_lastName = string.Empty;
_firstName = string.Empty;
}

public Employee(Guid employeeId, string lastName, string firstName)
{
_employeeId = employeeId;
_lastName = lastName;
_firstName = firstName;
}
}

Data Access Layer (DAL)

Create a new class named Employee. This class is only invoked by the BLL tier which in turn provides a crisp clean separation of logic.

public class Employee
{
private DbConnection conn;

public Employee()
{
conn = new DbConnection();
}

public List<Model.Employee> GetAllEmployees()
{
SqlCommand cmdSelectEmployees = null;
SqlDataReader rdrEmployees = null;
List<Model.Employee> employeeList = null;

try
{
SqlConnection dbConn = conn.DbConnect();
cmdSelectEmployees = new SqlCommand("select EmployeeID, LastName, FirstName from Employees order by LastName", dbConn);

dbConn.Open();

rdrEmployees = cmdSelectEmployees.ExecuteReader(CommandBehavior.CloseConnection);

if (rdrEmployees.HasRows)
{
employeeList = new List<Model.Employee>();

while (rdrEmployees.Read())
{
employeeList.Add(new Model.Employee(rdrEmployees.GetGuid(0), rdrEmployees.GetString(1), rdrEmployees.GetString(2)));
}
}
}
catch (Exception)
{
}
finally
{
if ((rdrEmployees != null) && !rdrEmployees.IsClosed)
{
rdrEmployees.Close();
}
}

return employeeList;
}
}

Utility Tier

This tier is used for anything that you will want to reuse. For example, the database connection is something that should only be wrote a single time.

public class DbConnection
{
private string _strConnectionString;

public SqlConnection DbConnect()
{
_strConnectionString = ConfigurationManager.ConnectionStrings["Thor"].ConnectionString;

SqlConnection conn = null;

try
{
conn = new SqlConnection(_strConnectionString);
}
catch (SqlException se)
{
throw new ApplicationException("The application was not able to connect to the database");
}
catch (Exception ex)
{
throw new ApplicationException("The application was not able to connect to the database");
}

return conn;
}
}

Business Logic Layer (BLL)

Create a new class named Employee. This classed is what the presentation layer will invoke in order to display the employee data we wish to return to the end user.

public class Employee
{
private readonly DAL.Employee _employeeDal;

public Employee()
{
_employeeDal = new DAL.Employee();
}

public List<RadDev.Model.Employee> GetAllEmployees()
{
Model.Employee employeeModel = new Model.Employee();

List<Model.Employee> employeeList = _employeeDal.GetAllEmployees();

return employeeList;
}
}

Presentation Tier

Now comes the step to put together the pieces of the puzzle. In four basic lines of code we have what we need to render the output.

protected void Page_Load(object sender, EventArgs e)
{
RadDev.BLL.Employee employeeBll = new RadDev.BLL.Employee();
List<RadDev.Model.Employee> employeeList = employeeBll.GetAllEmployees();
GridViewEmployees.DataSource = employeeList;
GridViewEmployees.DataBind();
}

The result is a GridView nicely populated:

employee gridview

That is all there is to it and as you can see N-Tier Architecture is a great way to separate logic in a controllable fashion. This is just one example and I urge you to dig into the details and find what works best in your case.

7 Comments

  1. Very well explained. Good article. Thanks!

  2. Thank you for this, it is one of the best and clearest explanations of N-Tier that I've seen.

  3. I’m confused as to why Utility is called a tier and not a layer. Unless there is some remoting going on, this library will run on the same machine as the BLL, DLL and website.

    • Your correct that utility will run on the same machine. Basically N-tier application architecture provides a model for developers to create a flexible and reusable application. By breaking up an application into tiers, developers only have to modify or add a specific layer, rather than have to rewrite the enitire application over, if they decide to change technologies or scale up. In the term “N-tier,” “N” implies any number — like 2-tier, or 4-tier; basically, any number of distinct tiers used in your architecture.

  4. Hi, I am not sure you are still updating this blog/article but I am gonna go ahead and take my chances anyway ;). First of all thanks for an awesome article, explanation doesn’t get any simpler than this. My question is, in the BLL where you are getting all the employees, you are also creating a Model object and once you have retrieved all the records from the DAL, you loop through them and write the individual bits to this Model object. However, it seems it doesn’t really serve any other purpose and also it seems that the same object is being overwritten so at the end of the loop, the model object (employeeModel) will contain only one value which is that of the last value of the list, could you please elaborate on the need of the model object in BLL in this method? Also, the GUI too seems to reference the Model layer, i would have supposed that it should only refer to BLL, what way it should really be? Lastly, would it have been of any advantage if the BLL object was singleton? Coz it seems, that if i needed to access the Employee data somewhere else in my GUI, I would be creating a new object everytime instead of using just one object, coz really EmployeeBLL is stateless as it just provides methods to retrieve and set data. I might be wrong but could you please shed some light on this.

    Thanks and Cheers
    Aman

    • To your first point concerning the BLL. You are correct, the model of the employee object serves no purpose, and it has been removed from the example.

      To your second point, the code behind the webform is only using the model here as an example to demonstrate that we do in fact have an object of employee that contains every employee we retrieved from the database. Typically, you may bind a datagrid directly to the method defined in the BLL, however there may be times when you may want to set labels, textboxes, and etc. to the employee model.

      Finally, it does make sense to use the singleton pattern in which you have outlined.

Leave a Reply

Required fields are marked *.