BLL & DAL: How are they different?

G

gnewsgroup

First, just in case, BLL = Business Logic Layer and DAL = Data Access
Layer.

I guess this is really a question about architecture. I believe there
are many architect here.

Software architecture is sorta new to me. I searched a little and did
find this:

http://www.velocityreviews.com/forums/t300246-bll-and-dal.html

It helped me understand a little bit about their differences and the
advantages of separating them. And now I do have one simple
question:

How do I know what needs to go to the BLL and what needs to go to the
DAL?

My guess is this: Any method that needs to do something like
connection.Open() and use a Sql command (including stored procedure)
should go into the DAL, right? Or is this a principle too naive in
software architecture?

Thanks for sharing your insights into this question.
 
M

Mark Rae [MVP]

First, just in case, BLL = Business Logic Layer and DAL = Data Access
Layer.

I guess this is really a question about architecture. I believe there
are many architect here.

Software architecture is sorta new to me. I searched a little and did
find this:

http://www.velocityreviews.com/forums/t300246-bll-and-dal.html

It helped me understand a little bit about their differences and the
advantages of separating them. And now I do have one simple
question:

How do I know what needs to go to the BLL and what needs to go to the
DAL?

My guess is this: Any method that needs to do something like
connection.Open() and use a Sql command (including stored procedure)
should go into the DAL, right? Or is this a principle too naive in
software architecture?

Not really, though stored procedures won't be in the DAL because they are
RDBMS objects...

Here's an easy (though perhaps over-simplistic) way to think of it.

Project A, Project B and Project C are all totally different, but they all
use SQL Server as their RDBMS. Therefore, they will all have different BLL
but can share the same DAL.

Project D, on the other hand, supports multiple RDBMS. Therefore, it might
have the same DAL as the Projects A, B & C, plus additional DALs which
support Oracle, MySQL, Postgre etc. Alternatively, it may have a single DAL
which supports multiple backend RDBMS through a factory pattern.

Essentially, the BLL and DAL should be completely independent to the extent
that you are able to change one of them without needing to change the
other...
 
G

gnewsgroup

Not really, though stored procedures won't be in the DAL because they are
RDBMS objects...

Here's an easy (though perhaps over-simplistic) way to think of it.

Project A, Project B and Project C are all totally different, but they all
use SQL Server as their RDBMS. Therefore, they will all have different BLL
but can share the same DAL.

Project D, on the other hand, supports multiple RDBMS. Therefore, it might
have the same DAL as the Projects A, B & C, plus additional DALs which
support Oracle, MySQL, Postgre etc. Alternatively, it may have a single DAL
which supports multiple backend RDBMS through a factory pattern.

Essentially, the BLL and DAL should be completely independent to the extent
that you are able to change one of them without needing to change the
other...

Not really, though stored procedures won't be in the DAL because they are
RDBMS objects...

Here's an easy (though perhaps over-simplistic) way to think of it.

Project A, Project B and Project C are all totally different, but they all
use SQL Server as their RDBMS. Therefore, they will all have different BLL
but can share the same DAL.

Project D, on the other hand, supports multiple RDBMS. Therefore, it might
have the same DAL as the Projects A, B & C, plus additional DALs which
support Oracle, MySQL, Postgre etc. Alternatively, it may have a single DAL
which supports multiple backend RDBMS through a factory pattern.

Essentially, the BLL and DAL should be completely independent to the extent
that you are able to change one of them without needing to change the
other...

Thank you. I understand that there are a lot of advantages of
separating them. But I am still not sure what goes into the BLL, and
what goes into the DAL. Sounds like both layers can *rightfully*
access the database? Any hint? Thanks.
 
M

Mark Rae [MVP]

Thank you. I understand that there are a lot of advantages of
separating them. But I am still not sure what goes into the BLL, and
what goes into the DAL. Sounds like both layers can *rightfully*
access the database?

Absolutely not! Only the DAL should access the RDBMS. If the BLL requires
interaction with the RDBMS, it uses the DAL...
 
S

sloan

//
Sounds like both layers can *rightfully*
access the database? //

In my opinion:

NO.


The DAL talks to the DB.

The BAL talks to the DAL. Using the 4 things I mention at my blog (the
"returns" from the DAL), you can get what you need done.
And you're safe if you ever need to change RDBMS's.
 
G

gnewsgroup

Absolutely not! Only the DAL should access the RDBMS. If the BLL requires
interaction with the RDBMS, it uses the DAL...

Fantastic, that sorta demystifies my confusion. Then, I have actually
been intuitively separating them in my web application. I've put most
methods that return DataTable, SqlDataReader, DataSet and those that
do insert, delete, update under App_Code.

Next question: Are event handlers considered in the presentation
layer? Should the code-behind file contain only event handlers and
everything else should go to either the BLL or DAL?

Thanks again.
 
G

gnewsgroup

//
Sounds like both layers can *rightfully*
access the database? //

In my opinion:

NO.

The DAL talks to the DB.

The BAL talks to the DAL. Using the 4 things I mention at my blog (the
"returns" from the DAL), you can get what you need done.
And you're safe if you ever need to change RDBMS's.

Thanks. I am still researching your blog. I have been intuitively
doing like what you said by putting those methods that return those
stuff in App_Code.

One question though: How can the DAL be completely independent of the
BLL? Don't we have to know what data we need in the BLL and then for
that purpose write a method in DAL that returns that data ?

Please demystify. Thanks.
 
G

gnewsgroup

Not really, though stored procedures won't be in the DAL because they are
RDBMS objects...

Here's an easy (though perhaps over-simplistic) way to think of it.

Project A, Project B and Project C are all totally different, but they all
use SQL Server as their RDBMS. Therefore, they will all have different BLL
but can share the same DAL.

Project D, on the other hand, supports multiple RDBMS. Therefore, it might
have the same DAL as the Projects A, B & C, plus additional DALs which
support Oracle, MySQL, Postgre etc. Alternatively, it may have a single DAL
which supports multiple backend RDBMS through a factory pattern.

Essentially, the BLL and DAL should be completely independent to the extent
that you are able to change one of them without needing to change the
other...

I guess I am repeating the question I asked sloan: How can the BLL and
DAL be completely independent of each other? Suppose, in (I guess)
the BLL, I need such fields from my database:

CustomerID, FirstName, LastName, Address.

Don't we have to write a method in the DAL that returns a DataTable
(or whatever) that contains such fields? And then some time later, we
decide to add a Phone field in the BLL, then don't we have to modify
the method in the DAL such that the Phone number is included?

See my confusion now? Thanks.
 
M

Mark Rae [MVP]

One question though: How can the DAL be completely independent of the
BLL? Don't we have to know what data we need in the BLL and then for
that purpose write a method in DAL that returns that data ?

No - that's the whole point!

Let's say you have a method in your DAL called FetchDataSet(.....) which
returns an ADO.NET DataSet object.

The FetchDataSet has two arguments: the name of the stored procedure, and a
collection of parameters to pass to the stored procedure. Additionally, it
might accept a connection string as a parameter or a pointer to indicate
which data provider to use if you've implemented a factory pattern. If you
adopt the Microsoft DAAB example, then the FetchDataSet will be a static
method.

Now that you have that method in your DAL, it will work for *any* method in
your BLL which needs to return a DataSet object from the RDBMS, e.g.

DataSet dsCustomers = MyDAL.FetchDataSet("SelectCustomers", colParameters);

DataSet dsProducts = MyDAL.FetchDataSet("SelectProducts", colParamaters);

etc.
 
M

Mark Rae [MVP]

I guess I am repeating the question I asked sloan: How can the BLL and
DAL be completely independent of each other? Suppose, in (I guess)
the BLL, I need such fields from my database:

See my reply of about a minute ago...
CustomerID, FirstName, LastName, Address.

Don't we have to write a method in the DAL that returns a DataTable
(or whatever) that contains such fields? And then some time later, we
decide to add a Phone field in the BLL, then don't we have to modify
the method in the DAL such that the Phone number is included?

No - you simply modify the stored procedure!
See my confusion now?

No.
 
R

radix

Consider layers just like real life abstraction. Let me give an
example of Automobile, a bus. The color of Bus, quality of seats, A/C
etc are presentation layers. The controls what driver uses like
breaks, steering wheel consider like Business Logic Layer. Further
details like how Engine or breaks works internally consider like Data
Access layer.

A person taking ride on bus as customer just sees outlook. Doesn't
need to know how bus is driven etc. A driver just need to know how
well bus is controlled and doesn't need to know internals of engines.
A mechanic although must know how to fix malfunctioning breaks etc.

As you see if engine isn't working, driver can't use bus. Thus to
function BLL properly DAL must work. The information is passed between
them through some known protocol. If engine is replaced by another
engine driver shouldn't feel any difference in operating controls.
There should be common way to work a BLL on various DAL with a common
interface.

Coming back to programming. DAL should deal with all code for SQL or
stored procedure. Must have inheritance where common aspects are on
base class and derived class implementation of each database or
otherwise. e.g. Various sub classes to handle SQL Server, Oracle,
etc.

BLL should have calculations for any business specifics. e.g. forumla
for interest in banking application. If you decided to calculate
interest as compound instead of simple interest, you should just
change BLL and not DLL. It would be bad design to save balance and
interest forumla in DAL and requiring changes in all DAL classes.

Final million dollar question is how to pass infomration between BLL
and DAL and vice versa. This is profound question with two answers
in .net, Customized objects and typed dataset. Dissucssion of this
beyond scope of this post. Google for "Customized objects vs typed
dataset" and hope you will get input from experts.

regards,
radix.
 
S

sloan

If you look at my blog, I handle this through "Layouts".
Although I use IDataReaders primarily.

...

When I need to add a new field...I change the

TSQL ( stored procedure)
the "Layout"

The Serializer, which converts the IDataReader to the business object and/or
collection.

...

If you're using strong datasets, or single datatables..you should only have
to change

TSQL
Add the column to the datatable/strong dataset.

Depending on which load mechanism you're using to push data from a stored
procedure into a datatable (or strong dataset).

...
 
Z

zhaojk

No - that's the whole point!

Let's say you have a method in your DAL called FetchDataSet(.....) which
returns an ADO.NET DataSet object.

The FetchDataSet has two arguments: the name of the stored procedure, and a
collection of parameters to pass to the stored procedure. Additionally, it
might accept a connection string as a parameter or a pointer to indicate
which data provider to use if you've implemented a factory pattern. If you
adopt the Microsoft DAAB example, then the FetchDataSet will be a static
method.

Now that you have that method in your DAL, it will work for *any* method in
your BLL which needs to return a DataSet object from the RDBMS, e.g.

DataSet dsCustomers = MyDAL.FetchDataSet("SelectCustomers", colParameters);

DataSet dsProducts = MyDAL.FetchDataSet("SelectProducts", colParamaters);

etc.

Again, fantastic. I do have some methods in some classes under
App_Code that take the name of a stored procedure and the parameters
the stored procedure takes. I did not know that I was separating DAL
from BLL, my intention was to be able to have more generickish methods
(to avoid writing very similar methods one after another) to call in
my code-behind.

Question: I suppose colParamaters should always be an array of string,
such that when we add more parameters to a stored procedure in the
RDBMS, we don't have to modify the code in the DAL, right?

BTW, do DAL mostly have static methods? Thanks once again.
 
S

Scott Roberts

Mark Rae said:
No - that's the whole point!

Let's say you have a method in your DAL called FetchDataSet(.....) which
returns an ADO.NET DataSet object.

The FetchDataSet has two arguments: the name of the stored procedure, and
a collection of parameters to pass to the stored procedure. Additionally,
it might accept a connection string as a parameter or a pointer to
indicate which data provider to use if you've implemented a factory
pattern. If you adopt the Microsoft DAAB example, then the FetchDataSet
will be a static method.

Now that you have that method in your DAL, it will work for *any* method
in your BLL which needs to return a DataSet object from the RDBMS, e.g.

DataSet dsCustomers = MyDAL.FetchDataSet("SelectCustomers",
colParameters);

DataSet dsProducts = MyDAL.FetchDataSet("SelectProducts", colParamaters);

Interesting.

What have you really gained here? The ability to swap out SqlClient for
OracleClient? I guess that's nice, but IMO doesn't go far enough. You still
have a very tight coupling between your BLL and RDBMS. Do you rely on the
BLL to interpret/decouple the data? I'd say that belongs in the DAL.
 
G

gnewsgroup

No - that's the whole point!

Let's say you have a method in your DAL called FetchDataSet(.....) which
returns an ADO.NET DataSet object.

The FetchDataSet has two arguments: the name of the stored procedure, and a
collection of parameters to pass to the stored procedure. Additionally, it
might accept a connection string as a parameter or a pointer to indicate
which data provider to use if you've implemented a factory pattern. If you
adopt the Microsoft DAAB example, then the FetchDataSet will be a static
method.

Now that you have that method in your DAL, it will work for *any* method in
your BLL which needs to return a DataSet object from the RDBMS, e.g.

DataSet dsCustomers = MyDAL.FetchDataSet("SelectCustomers", colParameters);

DataSet dsProducts = MyDAL.FetchDataSet("SelectProducts", colParamaters);

etc.

Again, fantastic. I do have some methods in some classes under
App_Code that take the name of a stored procedure and the parameters
the stored procedure takes. I did not know that I was separating DAL
from BLL, my intention was to be able to have more generickish methods
(to avoid writing very similar methods one after another) to call in
my code-behind.

Question: I suppose colParamaters should always be an array of string,
such that when we add more parameters to a stored procedure in the
RDBMS, we don't have to modify the code in the DAL, right?

BTW, do DAL mostly have static methods? Thanks once again.
 
G

gnewsgroup

If you look at my blog, I handle this through "Layouts".
Although I use IDataReaders primarily.

..

When I need to add a new field...I change the

TSQL ( stored procedure)
the "Layout"

The Serializer, which converts the IDataReader to the business object and/or
collection.

..

If you're using strong datasets, or single datatables..you should only have
to change

TSQL
Add the column to the datatable/strong dataset.

Depending on which load mechanism you're using to push data from a stored
procedure into a datatable (or strong dataset).

..

So, I suppose, in the method in your DAL, you don't pass the
parameters of a stored procedure one by one, but instead, you pass an
array, such that your method can take a different number of stored
procedure parameters, right?
 
S

sloan

If you're using Strong DataSets or a DataTable model, then

these get defined in their own assembly....and "float" outside of the
others.
They have also been called the "glue" assemblies.

If you get my code, you'll see that my DataSets project resides OUTSIDE of
the other 3 layers.
This is my glue assembly.



My blog has a bad URL, for the "birds eye" article.
Here is the correction.

http://msdn2.microsoft.com/en-us/library/ms978496.aspx

Read that article.
Go to lunch.
Come back and reread that article.
Bookmark it.
In a week, reread that article.


If you find this part of the article:
Deploying Business Entities

You can read...and that is where I'm saying the strong dataset (or now the
DataTable) will reside in its own assembly as a the "glue".
This is the idea presented in the first dotted (lineitem) in the section
labeled "Deploying Business Entities".

...

This is something where you're going to read 1 article and get it by just
reading.
You gotta try and code one up. (Which I know you are doing, and tryign to
find help via this post).
I'm just saying ... you gotta work with it some...and you gotta do some
reading and rereading as you get better with it.

I still read that article about every 6 months.....

You're leaning toward the DataTable/DataSet model. I've converted over to
custom business objects and custom collections.

Both are ok solutions. The article above .... is the best article I've
discovered which outlines the pros and cons of the approches.
That's why its a good "bird's eye view" article.
 
G

gnewsgroup

Consider layers just like real life abstraction. Let me give an
example of Automobile, a bus. The color of Bus, quality of seats, A/C
etc are presentation layers. The controls what driver uses like
breaks, steering wheel consider like Business Logic Layer. Further
details like how Engine or breaks works internally consider like Data
Access layer.

A person taking ride on bus as customer just sees outlook. Doesn't
need to know how bus is driven etc. A driver just need to know how
well bus is controlled and doesn't need to know internals of engines.
A mechanic although must know how to fix malfunctioning breaks etc.

As you see if engine isn't working, driver can't use bus. Thus to
function BLL properly DAL must work. The information is passed between
them through some known protocol. If engine is replaced by another
engine driver shouldn't feel any difference in operating controls.
There should be common way to work a BLL on various DAL with a common
interface.

Coming back to programming. DAL should deal with all code for SQL or
stored procedure. Must have inheritance where common aspects are on
base class and derived class implementation of each database or
otherwise. e.g. Various sub classes to handle SQL Server, Oracle,
etc.

BLL should have calculations for any business specifics. e.g. forumla
for interest in banking application. If you decided to calculate
interest as compound instead of simple interest, you should just
change BLL and not DLL. It would be bad design to save balance and
interest forumla in DAL and requiring changes in all DAL classes.

Final million dollar question is how to pass infomration between BLL
and DAL and vice versa. This is profound question with two answers
in .net, Customized objects and typed dataset. Dissucssion of this
beyond scope of this post. Google for "Customized objects vs typed
dataset" and hope  you will get input from experts.

regards,
radix.

Thank you very much for the nice example/analogy, which I can reuse in
the future if there is a need. :) It sounds to me like generic
programming, (not necessarily related to generic collections), in the
sense that we want to make our code generic enough such that when some
component changes, all others don't have to change.
 
S

sloan

//So, I suppose, in the method in your DAL, you don't pass the
parameters of a stored procedure one by one, but instead, you pass an
array, such that your method can take a different number of stored
procedure parameters, right?
//


Huh?

I pass arguments to methods in my DAL.

int employeeID, string lastName, string firstName

....

I don't think you've spent enough time with my example.....

...

To be honest, I don't like the uber super cool ..pass in a bunch of dynamic
parameter type stuff.


So I'll come back tomorrow, and see if you have any specific questions about
my example.

I realize you're on information overload right now.

Spend some time with the example. Run the code....and step through it.

...





If you look at my blog, I handle this through "Layouts".
Although I use IDataReaders primarily.

..

When I need to add a new field...I change the

TSQL ( stored procedure)
the "Layout"

The Serializer, which converts the IDataReader to the business object
and/or
collection.

..

If you're using strong datasets, or single datatables..you should only
have
to change

TSQL
Add the column to the datatable/strong dataset.

Depending on which load mechanism you're using to push data from a stored
procedure into a datatable (or strong dataset).

..

So, I suppose, in the method in your DAL, you don't pass the
parameters of a stored procedure one by one, but instead, you pass an
array, such that your method can take a different number of stored
procedure parameters, right?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top