Hi, We are using n-tier Architecture for developing software.Here i have mension all details of n-tier Architecture.Please check it. What is n-Tier Architecture? This is a very important topic to consider when developing an application.Many elements need to be considered when deciding on the architecture of the application, such as performance, scalability and future development issues. When you are deciding on which architecture to use, first decide on which of the three aforementioned elements you think is most valuable -- as some choices you make will impact on others. For example, some choices that boost performance will impact on the scalability or future development of your design, etc. Here we will talk generally about what n-Tier architecture is, and then we will have a look at different n-Tier architectures you can use to develop ASP.NET applications and issues that arise relating to performance, scalability and future development issues for each one. Firstly, what is n-Tier architecture? N-Tier architecture refers to the architecture of an application that has at least 3 "logical" layers -- or parts -- that are separate. Each layer interacts with only the layer directly below, and has specific function that it is responsible for. Why use n-Tier architecture? Because each layer can be located on physically different servers with only minor code changes, hence they scale out and handle more server load. Also, what each layer does internally is completely hidden to other layers and this makes it possible to change or update one layer without recompiling or modifying other layers. This is a very powerful feature of n-Tier architecture, as additional features or change to a layer can be done without redeploying the whole application. For example, by separating data access code from the business logic code, when the database servers change you only needs to change the data access code. Because business logic code stays the same, the business logic code does not need to be modified or recompiled. [Note] tier and layer mean the same thing [End Note] An n-Tier application usually has three tiers, and they are called the presentation tier, the business tier and the data tier.Let's have a look at what each tier is responsible for. Presentation Layer Presentation Layer is the layer responsible for displaying user interface and "driving" that interface using business tier classes and objects. In ASP.NET it includes ASPX pages, user controls, server controls and sometimes security related classes and objects. Business Tier Business Tier is the layer responsible for accessing the data tier to retrieve, modify and delete data to and from the data tier and send the results to the presentation tier. This layer is also responsible for processing the data retrieved and sent to the presentation layer. In ASP.NET it includes using SqlClient or OleDb objects to retrieve, update and delete data from SQL Server or Access databases, and also passing the data retrieved to the presentation layer in a DataReader or DataSet object, or a custom collection object. It might also include the sending of just an integer, but the integer would have been calculated using the data in the data tier such as the number of records a table has. BLL and DAL Often this layer is divided into two sub layers: the Business Logic Layer (BLL), and the Data Access Layers (DAL). Business Logic Layers are above Data Access Layers, meaning BLL uses DAL classes and objects. DAL is responsible for accessing data and forwarding it to BLL. In ASP.NET it might be using SqlClient or OleDb to retrieve the data and sending it to BLL in the form of a DataSet or DataReader. BLL is responsible for preparing or processing the data retrieved and sends it to the presentation layer. In ASP.NET it might be using the DataSet and DataReader objects to fill up a custom collection or process it to come up with a value, and then sending it to Presentation Layer. BLL sometimes works as just transparent layer. For example, if you want to pass a DataSet or DataReader object directly to the presentation layer. Data Tier Data tier is the database or the source of the data itself. Often in .NET it's an SQL Server or Access database, however it's not limited to just those. It could also be Oracle, mySQL or even XML. In this article we will focus on SQL Server, as it has been proven to be the fastest database within a .NET Application. Logical Layers vs. Physical Layers (Distributed) Logical Layers and Physical Layers are the ones that confuse people. Firstly, a logical layer means that layers are separate in terms of assembly or sets of classes, but are still hosted on the same server. Physical layer means that those assemblies or sets of classes are hosted on different servers with some additional code to handle the communication between the layers. E.g. remoting and web services. Deciding to separate the layers physically or not is very important. It really depends on the load your application expects to get. I think it's worth mentioning some of the facts that might affect your decision. Please DO note that separating the layers physically WILL slow your application down due to the delay in communicating between the servers throughout the network, so if you are using the physical layer approach, make sure the performance gain is worth the performance loss from this. Hopefully you would have designed your application using the n-Tier approach. If this is the case, then note that you can separate the layers in the future. Cost for deploying and maintaining physically separated applications is much greater. First of all, you will need more servers. You also need network hardware connecting them. At this point, deploying the application becomes more complex too! So decide if these things will be worth it or not. Another fact that might affect your decision is how each of the tiers in the application are going to be used. You will probably want to host a tier on a separate server if more than 1 service is dependent on it, e.g. You might want to host business logic somewhere else if you have multiple presentation layers for different clients. You might also want a separate SQL server if you have other applications using the same data. Performance, Scalability and Future Development As I said earlier, each choice you make in the architecture will affect one of the following: * Performance * Scalability * or Future Development. Here we will look at the most common choices you have to make in a typical ASP.NET application. I'll present you with some of the available options, cons and pros of each. [Note] You should develop an application bottom up. This means build the data tier layer first. You should always design all three layers before building the actual application. [End Note] Performance vs. Scalability vs. Future Development When deciding on your architecture, decide what your priority is going to be. If your application is time critical, then you might have to sacrifice its scalability and extendibility just because you need more procedural like class design, which will offer that. If you want scalability then you might have to sacrifice performance, because the scalability comes from scaling out and scaling out means communicating through a slower medium such as a LAN. Extensibility is a good thing to have but what's the point if you won’t be updating the application in the future, but instead be rewriting the whole thing? Think about whether you need extensibility or not because it can affect performance due to having more round trips to the database and also due to the simple fact that the size of the application will be bigger. Think about what you really need for the project you are doing not what other people are doing for their projects. Architecture is a topic that really doesn't have best practices so rather than going for architecture for all of your applications, think about different architecture for each of your applications. Presentation Tier Issues The presentation layer must be well planned before building it. If this layer is badly designed, it could impact on the applications performance and future development paths. I'll explain why. Firstly, let's start with performance. Remember how I said that the presentation layer 'uses' BLL to do any operations that need interaction with the data tier? No matter how well you've designed your BLL to reduce the round trips or unnecessary trips to the data tier, if the presentation layer code calls that method one or more times unnecessarily, you are still doing a round trip to the data tier. This impacts on your applications overall performance. Performance is also affected by the different types of controls you decide to use. For example, using a DataGrid instead of a DataList or Repeater will make a noticeable performance difference. So, when do you use a DataGrid and when do you use others? We will discuss this in a minute. Secondly, future development is also impacted upon if the presentation layer is badly designed. How? If you have repetitive HTML code in all pages of your website, what happens if you want to change a color of a table or something? Do you go to each page and change it? What would you do if your boss said "No, I don't like that... Change it back!"? You really need to implement a template system into your web pages, so when you make one change to your site design, it's propagated to all pages. Although not related to performance and future development, the presentation layer has another role in ASP.NET applications – security. You have 4 security options in ASP.NET, and we will have a look at each option in detail shortly. Before that though, let's get back to the DataGrid, DataList and Repeater issue. Data Grid, Data List, Repeater Knowing the differences between these controls is very important because they are very different controls made for different uses, but people tend to get them confused. Performance wise, you must always use a Repeater wherever possible. It is the fastest control out of the three. Unfortunately, it is also very limited in what it can do. All a repeater can do is iterate through the data source and display its properties. A data source can be a data object such as a DataReader or dataset, but it can also be your custom collection that implements the IEnumerable and/or the IEnumerator interface. This is very good for displaying read only items such as list of news headlines, a summary of recent articles, etc. There are times when you want to be able to "select" a row. When the row is selected, you want different item templates to be displayed. This situation is when you use a data list. DataLists allow you to select a row and display data using different templates. This is very useful for items that might need some frequent modification such as a list of news headlines for administrators where you want administrators to be able to edit headlines, etc. The DataGrid is an interesting control. I always use it when I have a dataset as my data source. Although it's really slow, it is very flexible. It's also capable of producing a professional looking list or grid automatically. It knows the database's schema. It knows the type of fields and displays them accordingly. But one of the best features it has is its ability to allow editing of the data without having us code any postback functions, etc. I find it great for administrative sections as it is not used very often but offers the greatest flexibility and convenience. If you need the greatest performance possible, however, then don't use a DataGrid. Security In ASP.NET there are 4 security models that you can use in your web applications. 1. Form security This is probably the most commonly used security model in ASP.NET web sites. It's very convenient to use and is perfect for most applications. If you need role based security then typically this is the way to go. 2. Passport If you want your visitors to be able to use their passport account at your site, you can implement the passport security model. To use this security model you need to be able to access the Internet, so it's not really suitable for intranet applications. It's quiet flexible and quite effective, however. As a passport user myself, its very convenient not to login to each and every site I visit. But all of this come at an expensive dollar price! 3. Custom Security If you need a more complex security system, then you will need to implement your own security system. This is typically done by building your own principal and identity classes (implementing the IPrincipal an Iidentity interfaces). I've implemented permission-based security using this method and it was very successful. 4. Windows Security This is perfect for intranet sites. It communicates to an Active Directory for user authentication information where all of the groups, permissions and users are managed. Business Tier Issues Building an efficient and elegant Business Tier is very important. If your business tier code is slow and hard to understand, then there is no hope of making an application fast or extendable in the future. It doesn't matter how efficient your presentation code is (by calling on the business tier less often) -- if your business tier is making unnecessary round trips to the database, then your application as a whole will be slow. This is a little different from what I've said about the presentation tier. If the presentation tier is slow, then that part of the application might be slow, but if its the business tier that's slow, then it will affect all applications that use the business tier, which can be ASPX pages as well as web services you provide to other businesses. DataSet VS DataReader The issue of the DataSet versus the DataReader for some reason always seem to put people in doubt. I've come across a lot of people who weren’t sure which one to use. Let's clarify their uses now. In ASP.NET, always use a DataReader unless you need to serialize it or pass it to the next tier. There are some books and articles that tell you to use a DataSet over a DataReader every time. In my opinion that's not good practice because a DataSet eats up your resources very, very quickly (a DataSet actually is filled using a DataReader). I rarely use a DataSet in my web applications. I always use a DataReader, and if I need to pass it to the next tier I make my own custom collection class and pass that object between tiers. I just find a DataSet too heavy for web applications, though for a web service it's better to use a DataSet than a custom collection. [Note] I'm talking about just the web application. This becomes a different story if you're designing BLL for both Web AND Win forms [End Note] Some people might have heard of typed DataSets, which are classes that inherit from the DataSet. It is used in Duwamish7 and is quite popular in the .NET community. It has a very elegant design, but compromises your application’s performance. If elegance is more important (for future upgrades), then a typed dataset is a great alternative to your own custom collection. VS.NET has great support for them too!
Saturday, 6 August 2011
C# .Net project architecture Designing
.NET Application Architecture: the Data Access Layer
Designing and building a robust data access layer
Building an understanding of architectural concepts is an essential aspect of managing your career. Technical interviews normally contain a battery of questions to gauge your architectural knowledge during the hiring process, and your architectural ability only becomes more important as you ascend through the ranks. So it's always a good idea to make sure you have a good grasp on the fundamentals. In this article you will explore a key component of application architecture known as the Data Access Layer (DAL), which helps separate data-access logic from your business objects. The article discusses the concepts behind the DAL, and the associated PDF file takes a look at a full-blown DAL implementation. This is the first in a series of articles discussing some of the cool things you can do with a DAL, so the code and concepts in this article form the base for future discussions.
Layered design and the data access layer
Layered application designs are extremely popular because they increase application performance, scalability, flexibility, code reuse, and have a myriad of other benefits that I could rattle off if I had all of the architectural buzzwords memorized. In the classic three tier design, applications break down into three major areas of functionality:
- The data layer manages the physical storage and retrieval of data
- The business layer maintains business rules and logic
- The presentation layer houses the user interface and related presentation code.
Inside each of these tiers there may also exist a series of sub-layers that provide an even more granular break up the functional areas of the application. Figure 1 outlines a basic three tired architecture in ASP.NET along with some of the sub-tiers that you may encounter:
Figure 1 – Three tiered ASP.NET application with sub-tiers
The presentation tier
In the presentation layer, the code-behind mechanism for ASP.NET pages and user controls is a prominent example of a layered design. The markup file defines the look and layout of the web form and the code behind file contains the presentation logic. It's a clean separation because both the markup and the code-behind layers house specific sets of functionality that benefit from being apart. Designers don't have to worry about messing up code to make user interface changes, and developers don't have to worry about sifting through the user-interface to update code.
The data tier
You also see sub-layers in the data tier with database systems. Tables define the physical storage of data in a database, but stored procedures and views allow you to manipulate data as it goes into and out of those tables. Say, for example, you need to denormalize a table and therefore have to change its physical storage structure. If you access tables directly in the business layer, then you are forced to update your business tier to account for the changes to the table. If you use a layer of stored procedures and views to access the data, then you can expose the same logical structure by updating a view or stored procedure to account for the physical change without having to touch any code in your business layer. When used appropriately, a layered design can lessen the overall impact of changes to the application.
The business tier
And of course, this brings us to the topic of business objects and the Data Access Layer (also known as the DAL), two sub-layers within the business tier. A business object is a component that encapsulates the data and business processing logic for a particular business entity. It is not, however, a persistent storage mechanism. Since business objects cannot store data indefinitely, the business tier relies on the data tier for long term data storage and retrieval. Thus, your business tier contains logic for retrieving persistent data from the data-tier and placing it into business objects and, conversely, logic that persists data from business objects into the data tier. This is called data access logic.
Some developers choose to put the data access logic for their business objects directly in the business objects themselves, tightly binding the two together. This may seem like a logical choice at first because from the business object perspective it seems to keep everything nicely packaged. You will begin noticing problems, however, if you ever need to support multiple databases, change databases, or even overhaul your current database significantly. Let's say, for example, that your boss comes to you and says that you will be moving your application's database from Oracle to SQL Server and that you have four months to do it. In the meantime, however, you have to continue supporting whatever business logic changes come up. Your only real option is to make a complete copy of the business object code so you can update the data access logic in it to support SQL Server. As business object changes arise, you have to make those changes to both the SQL Server code base and the Oracle code base. Not fun. Figure 2 depicts this scenario:
Figure 2 – Business objects with embedded data access logic
A more flexible option involves removing the data access logic from the business objects and placing it all in a separate assembly known as the DAL. This gives you a clean separation between your business objects and the data access logic used to populate those business objects. Presented with the same challenge of making the switch from Oracle to SQL Server, you can just make a copy of the Oracle DAL and then convert it to work with SQL Server. As new business requirements come in, you no longer need to make changes in multiple locations because you only maintain a single set of business objects. And when you are done writing the SQL Server DAL, your application has two functional data access layers. In other words, your application has the means to support two databases. Figure 3 depicts separating data access logic out into a separate DAL:
Figure 3 – Business objects with separate data access layer
Design principals in the data access layer
The objective of the DAL is to provide data to your business objects without using database specific code. You accomplish this by exposing a series of data access methods from the DAL that operate on data in the data-tier using database specific code but do not expose any database specific method parameters or return types to the business tier. Any time a business object needs to access the data tier, you use the method calls in the DAL instead of calling directly down to the data tier. This pushes database-specific code into the DAL and makes your business object database independent.
Now wait, you say, all you've accomplished is making the business objects dependent on the DAL. And since the DAL uses database-specific code, what's the benefit? The benefit is that the DAL resides in its own assembly and exposes database-independent method signatures. You can easily create another DAL with the same assembly name and an identical set of method signatures that supports a different database. Since the method signatures are the same, your code can interface with either one, effectively giving you two interchangeable assemblies. And since the assembly is a physical file referenced by your application and the assembly names are the same, interchanging the two is simply a matter of placing one or the other into your application's bin folder.
Note: You can also implement a DAL without placing it in a separate assembly if you build it against a DAL interface definition, but we will leave that to another article.
Exchanging Data with the DAL
Now the question is: how do you exchange data between your business objects, the DAL, and vice versa? All interaction between your business objects and the DAL occurs by calling data access methods in the DAL from code in your business objects. As mentioned previously, the method parameters and return values in the DAL are all database independent to ensure your business objects are not bound to a particular database. This means that you need to exchange data between the two using non-database-specific .NET types and classes. At first glance it may seem like a good idea to pass your business objects directly into the DAL so they can be populated, but it's just not possible. The business object assembly references the DAL assembly, so the DAL assembly cannot reference the business object assembly or else you would get a circular reference error. As such, you cannot pass business objects down into the DAL because the DAL has no concept of your business objects. Figure 4 diagrams the situation:
Figure 4 – Business objects assembly references the DAL, so the DAL has no concept of business objects
The custom class option
One option is to pass information in custom classes, as long as those custom classes are defined in an assembly that both the business object and DAL assemblies can reference. From an academic standpoint, this approach is probably the truest form of a data abstraction for a DAL because you can make the shared classes completely data-source independent and not just database independent. Figure 5 depicts how the business object assembly and the DAL assembly can both reference a shared assembly:
Figure 5 – The business object assembly and the DAL assembly both reference a shared assembly, so they can exchange information using classes and data structures from the shared assembly.
In practice, I find that building out custom classes solely to exchange data doesn't give you much return for your effort, especially when there are other acceptable options already built into .NET.
The XML approach
You could opt to use XML since it's the poster child of flexibility and data-source independence and can easily represent any data imaginable. Of course, it also means that you will be doing a lot of XML parsing work to accommodate the data exchange, and I'm not a fan of extra work.
The database interface approach
You could also use the database interfaces from the System.Data namespace to exchange data between business objects and the DAL. Database specific objects such as SqlDataReader, SqlCommand, andSqlParameter are tied to SQL Server, and exposing them from the DAL would defeat the purpose. However, by exposing an IDataReader, IDBCommand, or IDataParameter object you do not tie yourself to particular database so they are an acceptable option, though not my first choice.
From an academic standpoint, the database interface objects do tie you to using a "database management system" even though they do not tie you to a specific database. Pure academics will tell you that the DAL should be "data-source independent" and not just "database independent" so be prepared for that fight if you have a Harvard or Oxford grad on your development team who majored in theoretical application design. Nobody else on the planet cares because the chances of your application moving away from a database system are fairly slim.
My preferred approach: DataSets
Another option for passing information, and the one that I gravitate towards because of its flexibility, is the DataSet. Microsoft created the DataSet class specifically for storing relational information in a non-database specific data structure, so the DataSet comes highly recommended for returning query information containing multiple records and or tables of data. Your work load shouldn't suffer too significantly from using the DataSet because DataAdapters, which fill DataSets with information, already exists for most database systems. Furthermore, getting data out of the DataSet is fairly easy because it contains methods for extracting your data as tables, rows, and columns.
Also note that a DataSet is technically data-source independent, not just database independent. You can write custom code to load XML files, CSV files, or any other data source into a DataSet object. Additionally, you can even manipulate and move information around inside the DataSet, something that is not possible with the database interfaces from the System.Data namespace.
Exchanging non-relational data
Of course, you also deal with non-relational information when you pass data back and forth between your business objects and the DAL. For example, if you want to save a single business object to the data-tier, you have to pass that business object's properties into the DAL. To do so, simply pass business object properties into the DAL via native .NET type method parameters. So a string property on your business object is passed into the DAL as astring parameter, and an int property on your business object is passed into the DAL as an int parameter. If the DAL updates the business object property, then you should mark the parameter with the ref modifier so the new value can be passed back to the business object. You can also use return values to return information as the result of a function when the need arises. Listing 1 contains examples of method signatures that you may need in the DAL if you have a Person business object in your application:
Listing 1 – Data access layer method signature examples
DataSet Person_GetAll()
{
//Returns a DataSet containing all people records in the database.
}
DataSet Person_GetByPersonID(int personID)
{
// Queries the database for the particular user identified by
// personID. If the user is located then the DataSet contains a
// single record corresponding to the requested user. If the user
// is not found then the DataSet does not contain any records.
}
bool Person_Save(ref int personID, string fname, string lname, DateTime dob)
{
// Locates the record for the given personID. If the record exists,
// the method updates the record. If the record does not exist, the
// method adds the record and sets the personID variable equal to
// the identity value assigned to the new record. Then the method
// returns the value to the business layer because personID is
// marked with the ref modifier.
}
int Person_DeleteInactive()
{
//Deletes all inactive people in the database and returns a value
//indicating how many records were deleted.
}
Data service classes
Normally you have one data access method in your DAL for each scenario in which you need to exchange data between a business object and the database. If, for example, you have a Person class then you may need data access methods like Person_GetAll, Person_GetPersonByID, Person_GetByLoginCredentials,Person_Update, Person_Delete, and so on, so you can do everything you need to do with a Person object via the DAL. Since the total number of data access methods in your DAL can get fairly large fairly quickly, it helps to separate those methods out into smaller more manageable Data Service Classes (or partial classes in .NET 2.0) inside your DAL. Aside from being more manageable from a shear number standpoint, breaking down the DAL into multiple data service classes helps reduce check-out bottle necks with your source control if you have multiple developers needing to work on the DAL at the same time. Figure 6 depicts a DAL broken down into three individual data service classes:
Figure 6 – Breaking down the DAL into multiple data service classes
Notice that all of the data service classes depicted in Figure 3 derive from a single base class namedDataServiceBase. The DataServiceBase class provides common data access functionality like opening a database connection, managing a transaction, setting up stored procedure parameters, executing commands, and so forth. In other words, the DataServiceBase class contains the general database code and provides you with a set of helper methods for use in the individual data service classes. The derived data service classes use the helper methods in the DataServiceBase for specific purposes, like executing a specific command or running a specific query.
Putting theory into practice: the demo application
At this point you should have a descent understanding of what the data access layer is and how it fits into an application from an architectural point of view. Theory is great, but at some point you have to quit talking and start coding. Of course, going from theory to practice is no trivial step, so I wanted to make sure you had a solid example to use as a foundation both in terms of code and understanding.
At the top of this article is a link to a zip file containing two items: a demo application containing a DAL implementation and a Building a Data Access Layer PDF that explains the code in detail. The application is fairly simple, a two page web app that allows you to view / delete a list of people on one page and to add / edit those people on another. However, it does implement all of the design principles that we've covered here. Enjoy!
Test your implementation of Damon's .NET Data Access Layer...against realistic SQL Server data loads, using Red Gate's SQL Data Generator.
Subscribe to:
Posts (Atom)