As a developer, the .NET framework and Visual Studio present many choices for choosing the right architecture, from placing the data access code directly in the UI through datasets and data source controls, to creating a data access layer that talks to the database, all the way to creating an n-tier architecture approach that consists of multiple layers, and use data-transfer objects to pass data back and forth.
If you’ve ever wondered why you should use layers and what the benefits are, this article is for you. This article delves into the use of layers and how they can benefit any application.
What is a Layer?
A layer is a reusable portion of code that performs a specific function. In the .NET environment, a layer is usually setup as a project that represents this specific function. This specific layer is in charge of working with other layers to perform some specific goal. In an application where the presentation layer needs to extract information from a backend database, the presentation would utilize a series of layers to retrieve the data, rather than having the database calls embedded directly within itself. Let’s briefly look at the latter situation first.
When the .NET 2.0 framework became available to the world, there were some neat features that allowed the developer to connect the framework’s GUI controls directly to the database. This approach is very handy when rapidly developing applications. However, it’s not always favorable to embed all of the business logic and data access code directly in the web site, for several reasons:
- Putting all of the code in the web site (business logic and data access) can make the application harder to maintain and understand.
- Reusing database queries in the presentation layer often isn’t done, because of the typical data source control setup in the ASP.NET framework.
- Relying on the data source controls can make debugging more difficult, often due to vague error messages.
So in looking for an alternative, we can separate the data access code and business logic into separate “layers”, which we’ll discuss next.
The Data Layer
The key component to most applications is the data. The data has to be served to the presentation layer somehow. The data layer is a separate component (often setup as a separate single or group of projects in a .NET solution), whose sole purpose is to serve up the data from the database and return it to the caller. Through this approach, data can be logically reused, meaning that a portion of an application reusing the same query can make a call to one data layer method, instead of embedding the query multiple times. This is generally more maintainable.
But the question is how is the data returned? Multiple frameworks employ different techniques, and below is a summary:
- ADO.NET – Built into the .NET framework, ADO.NET contains a mechanism to query data out of the database and return it to the caller in a connected or disconnected fashion. This is the most common approach to working with data, because it’s already readily available. See more at: http://en.wikipedia.org/wiki/ADO.NET.
- Table Adapters/Strongly-Typed Datasets – Strongly-typed datasets and table adapters provide a similar means to querying the data through ADO.NET, but add strong-typing features, meaning custom objects are generated for you to work with. See more here.
- Enterprise Library – Enterprise library Data Access Application Block provides a flexible way to connect to databases of multiple types, without having to know anything about that database, through an abstract approach. See more at: http://msdn2.microsoft.com/en-us/magazine/cc188705.aspx (read part one first).
- LINQ-to-SQL – LINQ to SQL is an ORM tool that uses a DataContext object as the central point to query data from the database. See more here. (read parts one through eight first).
- Auto-Generated Code – Tools like CodeSmith Studio automatically generate the code for you based upon a database schema. Simply writing a script to output the code you want to use and the backend is generated in a short amount of time. See more at: http://community.codesmithtools.c om/blogs/tutorials/archive/2006/02/13/nettiers.aspx.
Most (if not all) options above take advantage of the CRUD (create, read, update, or delete) operations that databases support, so all of that is available as shown above. There are plenty of resources online to help you get started. To see an overview of some of the options, please read this.
Though a web site could talk to the data access layer directly, it usually goes through another layer called the business layer. The business layer is vital in that it validates the input conditions before calling a method from the data layer. This ensures the data input is correct before proceeding, and can often ensure that the outputs are correct as well. This validation of input is called business rules, meaning the rules that the business layer uses to make “judgments” about the data.
However, business rules don’t only apply to data validation; these rules apply to any calculations or any other action that takes place in the business layer. Normally, it’s best to put as much logic as possible in the business layer, which makes this logic reusable across applications.
One of the best reasons for reusing logic is that applications that start off small usually grow in functionality. For instance, a company begins to develop a web site, and as they realize their business needs, they later decide to add a smart client application and windows service to supplement the web site. The business layer helps move logic to a central layer for “maximum reusability.”
The ASP.NET web site or windows forms application (the UI for the project) is called the presentation layer. The presentation layer is the most important layer simply because it’s the one that everyone sees and uses. Even with a well structured business and data layer, if the presentation layer is designed poorly, this gives the users a poor view of the system.
It’s best to remove as much business logic out of the UI and into the business layer. This usually involves more code, but in my mind, the excess time (which ranges from minimal to moderate, depending on the size of the application) pays off in the end.
However, a well-architected system leaves another question: how do you display it in an ASP.NET or windows application? This can be more of a problem in ASP.NET, as the controls are more limited to the type of inputs they can receive. If you use certain architectures, like passing datasets from the data to the presentation layer, this isn’t as much of a challenge; however, the challenge can come with business objects that support drill-through business object references.
Why Separating Logic Is Useful
You may wonder why it is important to move as much logic outside the presentation layer and into the business layer. The biggest reason is reuse: logic placed in a business layer increases the reusability of an application. As applications grow, applications often grow into other realms. Applications may start out as a web application, but some of the functionality may later be moved to a smart client application. Portions of an application may be split between a web site and a web or windows service that runs on a server. In addition, keeping logic helps aid in developing a good design (sometimes code can get sloppier in the UI).
However, there are some caveats to this: it takes a little longer to develop applications when most of the logic resides in the business layer. The reason is this often involves creating several sets of objects (data layer and access code, plus business objects) rather than embedding it in the application. The extra time that it takes to do this can be a turnoff for some managers and project leads, especially because it often requires you to be knowledgeable about object-oriented programming, more than most people are comfortable with.
Although embedding code in the UI is easier, in most cases I don’t believe it’s the best approach. A layered approach is often a better approach because it pays dividends down the road. This is because as more and more code is developed, the following happens:
- Code is copied and pasted frequently, or code is reused in classes that could easily be moved to a business layer.
- Code that is very similar is often copied and pasted with slight modification, making duplication harder to track down.
- It’s harder to maintain; even though applications with business objects are larger applications, they usually are structured better.
- Code is harder to unit test, if unit testing is available at all. Web applications and windows forms projects are hard to use unit testing with.
A good architecture is often harder to implement, but is easier to maintain because it often reduces the volume of code. This means that hours spent supporting an application are reduced.
Using a separation of layers can aid in development of distributed applications. Because the code is broken up into layers, a layer that facilitates the use of remoting or web services can be added to the project, with a minimal amount of work.
When developing a business object architecture, it’s good to know about the many design patterns that are out there. There are many websites, blogs, and books related to the subject of design patterns. One of the more well-known books on the subject is titled “Design Patterns,” whom the authors are often referred to as the Gang of Four.
Another useful development technique is called Refactoring, or improving the quality of your code by making small changes to the way it works. This involves moving code into a method, or moving a method from one object to another, in a systematic, logical way. Martin Fowler has written a great book on this subject, called “Refactoring, Improving the Design of Existing Code.” There are plenty of books on the subject; this one is the source that helped me to understand refactoring the most.
There are also tools on the market that can help you refactor in a faster way. One of those tools is Resharper by Jet Brains, which looks for a lot of code patterns and refactors them in a way that is useful. Some of the other refactoring tools that I heard about are Refactor Pro by DevExpress (free for VB.NET and ASP.NET), Visual Assist X by Whole Tomato Software, and Just Code by OmniCore.