Introduction
Previously, I wrote an article about building an n-tier application in VB.NET. If you check the article, I was at a certain level of programming at that time and I have utilized wizards that were included in Visual Studio, and that never give me a chance to understand what the wizard does behind the scenes. I found myself stuck again because of the limitation of this wizard supplied by VS. Don't get me wrong, they help, but only when you develop at a beginner level. Just imagine if you are new to .NET and you use a data adapter wizard to get data from two tables using a join. Well the wizard will not complain, but when it comes time to update, it's a problem for you. The wizard will not be able to help you, then you have to code your data layer yourself. Imagine telling a new person in programming that he must use a data layer. He won't understand until you explain step by step what is a data layer. Now in this article, we are going to create an n-tier application without any wizard. We will concentrate on inserting only until the next article. This is an introduction until the next article.
This is how a tier will look like when it's complete:
Background
This is an n-tier application, that has physical tiers separated. Of course, we have to design the user interface and come back to DAL, but I think it's not a good programming practice to have a lot of text in your presentation layer. Don't get me wrong, it does not affect anything from the system, but if you can look at your presentation layer(form), Visual Studio will generate its code and believe me, it does not look good to write such big comments in there. OK, let's get back to the topic.
I love n-tier applications, they are easily maintained, and easy to design. So the whole project consists of tier, the PL(presentation layer) that is your user interface, ASP.NET pages, BLL (business logic layer) those are your classes that take care of formatting your data. Validating data and other things we will do later in this project and the DAL (data access layer) in this layer, that's where we run SQL queries to the SQL database or Access or Oracle. Please note that in this layer, we don't take care of the errors.
Using the Code
We are going to use multiple comments in our article and we are going to use C# as our language.
Points of Interest
While writing code in n-tier applications using wizards and naked SQL statements, I have learned a lot of things that led me to write this article. I once promised Dave that I will never use a wizard to do my database work and it's working for me, and I have learned again to use both VB.NET and C#, thanks to CodeProject.
History
I would like to take this chance and dedicate this article to the careways group I went for an interview that gave me a valiant to code in C# and believe me, it was so easy to work with it. Academically, I used to develop in C++ under the Linux environment and Java. The idea of OOP in C++ or Java was a great experience and I longed with all my heart to work with that. I preferred C++ over Java, because of multiple inheritance, but now C# will have to do like Java and implement interfaces. Still I am very grateful that I am back to that world. thanks to the careways group team, ian roets and his team, I say I would love to work with you, you brought me back to the world, when VB.NET kept me captive with its user friendly IDE. Lastly guys don’t laugh at this, this is not a joke , I keep on using “//” to comment my VB.NET code, do you see what you have done? I love it because I can interchange the languages, but for now I will stick to C#.
Start
Now before we start coding, let's build our project and understand it. Open Visual Studio and select a new project, choose C# Windows project and name it "client
". This is going to be our presentation layer and add some textboxes so that it will look like this:
After you are done, go to file, add a new project and select a classlibrary and name it "clsbll
". After you did that, note that in your clsbll
project, there will be "class1
". change it to "bll
", and add another project again and name it "clsdal
" and do the same thing by renaming the class1
to "DAL
" and when you are done, your solution explorer will look like this:
Now, there are three projects in this solution. For this part of this article, we are going to look at the insert only. We have seen our presentation layer, then now it's time for database work. Let's just create our own database and table that we can even use for part II of this article.
Database Work (SQL)
In my case, I have both SQL 2000 and SQL 2005. You can use any of your choice. If you use 2000, go to query analyzer and start coding. Remember even if you have SQL 2005, we don't use wizards to do our database work. Let's create a database, like this:
create database valrollclients
OK, now it's time to create our table for clients:
create table client_details
(
client_id int identity(100,01) primary key not null,
client_name char(12) null ,
client_lastname char(15) null,
client_age int null
)
So our database and our tables are in place. What we need is a stored procedure that we are going to use. Let's define our stored procedure:
set nocount on
create procedure prcinsert_client
(
@client_name char(12) ,
@client_lastname char(15) ,
@client_age int
)
as
insert into client_details
values(@client_name,@client_lastname,@client_age)
Now our database work is done in SQL. Let's go back to Visual Studio.
DAL(Data Access Layer)
Now our presentation layer is done but not with code, now we need to start from back to front. We are going to start by coding the DAL. Open the DAL class. We need to add namespaces that are not automatically available. Let's import those namespaces.
using system.data.sqlclient;
using system.data;
public class dal
{
string strcon = @"user id = sde ; password = passrd;
server =dfgserver;database =valrollclients";
sqlcommand cmdinserted;
sqlconnection con;
public void insert_clients(string client_name, string client_lastname,
int client_age)
{
cmdinserted = new sqlcommand();
cmdinserted.commandtext = "[dbo].[prcinsert_client]";
cmdinserted.commandtimeout = 0;
cmdinserted.commandtype = commandtype.storedprocedure;
con = new sqlconnection(strcon);
cmdinserted.connection = con;
cmdinserted.parameters.add("@client_name",
sqldbtype.varchar, 12).value = client_name;
cmdinserted.parameters.add("@client_lastname",
sqldbtype.varchar, 15).value = client_lastname;
cmdinserted.parameters.add("@client_age ",
sqldbtype.int, 4).value = client_age;
try
{
con.open();
cmdinserted.executenonquery();
con.close(); }
catch (sqlexception) {
throw; }
}
}
Now that was our DAL class which has only one method. Now remember that our client should not access our DAL directly and that means our BLL should be the middleman between the DAL and the client. That means we have to add a reference in a BLL project to a DAL project and in the client project, we are going to add a reference to only a BLL.
BLL(Business Logic Layer)
Now in our BLL, we are going to handle all the business rules, errors. As you have seen in our DAL class, we only trapped the exceptions but never displayed them from there, we only threw them to the calling method, and that method will only come from BLL and the BLL will send the message to the client. That means BLL is meant to control the validity and consistency of data between the layers, the data that is coming from DAL is made ready to be presented by the client and the data that is coming from the client application (presentation layer) is checked for validity and passed to DAL. So the first thing we are going do is to add a reference on the BLL to the DAL project, so that we can call the method save. After we have done that, let's go and code our BLL.
public class bll
{
public int save_client(string clientname, string clientlastname, string clientage)
{
boolean bopassed = true;
bopassed = check_rules(clientname, clientlastname, clientage);
clsdal.dal obj = new clsdal.dal();
int Res = 0;
try
{
if (bopassed == true) {
obj.insert_clients
(clientname, clientlastname, convert.toint32(clientage));
Res = 1;
}
else {
Res = 0;
}
}
catch (SqlException)
{
throw;
}
return Res;
}
private boolean check_rules(string client_name,string clientlastname,
string clientage)
{
boolean bolres = true; if (client_name == "") {
bolres = false; }
if (clientlastname == "")
{
bolres = false;
}
if (clientage =="")
{
bolres = false;
}
return bolres;
}
}
Now that our BLL is complete and commented and done, let's go to our client again and finish the job.
PL(Presentation Layer)
This is the part that our everyday users see and use. Now we have to set the reference so that we can use the functions and methods of our BLL, after you are done setting the reference, double click on the save button and start coding.
clsbll.bll obj = new clsbll.bll();
string clientname = txtclientname.text ;
string clientlastname = txtclientlastname.text;
string clientage = txtclientage.text;
int Res = 0;
try
{
Res = obj.save_client(clientname,clientlastname,clientage);
}
catch(SqlException ex)
{
MessageBox.Show(ex.Message);
}
if(res == 1)
{
MessageBox.Show("Data Saved");
}
else
{
MessageBox.Show("Data not Saved");
}
After you are done, remember that there is a clear button, this is just an extra thing, it has nothing to do with n-tier. There is a clear button. Double click on it to add code.
txtclientname.clear();
txtclientlastname.clear() ;
txtclientage.clear();
This code will clear the textboxes when pressed. Now if we test our application like this, press F5 on our keyboard and you will see your PL(presentation layer), if you try to click save button without any input, you will get an error message that was trapped in our BLL. This shows that the BLL is good and responsible for messages and error handling. That means the check_rules
function returned a false
and again that means the rules had been violated.
And if you add input and try it again, you will receive a message that confirmed that the rules had not been violated.
To confirm that the record has been saved, without relying on our message that we displayed in the BLL, you can run a select *
statement in your SQL database, and you will see the record that you have entered.
Conclusion
We wrote this application without any help from a wizard, but for now we added only into our table. In part II of this article, we are going to update, delete and search the datagrid
. The data will be coming from a join
, and that means the datagrid
will be displaying data from two tables as if they are from one table. Now the tricky part that a wizard cannot handle is the update
and delete
. I am going to explain how can we design our DAL and our BLL without a wizard using storedprocedures in n-tier. I thank you all for your support and don't punish me for not formatting this article neatly. I wrote the tags myself and it was a pain, I could not get a toolbar in CodeProject, but CodeProject's Sean tried to get me the toolbar, I thank you for your help. I believe the article that was been deleted yesterday was going to be better than this one. I explained well and clear, if I was given a chance to finish it, it would be nice for beginners.