?
Solved

Passing data from DAL to BLL to PL using vb.net in winforms

Posted on 2010-09-15
27
Medium Priority
?
2,124 Views
Last Modified: 2012-05-10
Hi Experts,
I am designing  a desktop app using VS 2008 and MS Access.  It is going to be a 3-tier app.  I am experimenting different things that my app will need.  For example,
My Form(PL) has this combobox. UI will call BL to get All the Product Categories, assign Combobox.Datasource= BL.GetCategories(list or array())
Product Categories has attributes like Category_Name, Category_ID, Category)Type etc.

BL will ask the DAL to get the categories from the Access database. Can I use arrays or lists to be passed to BL? How do I pass objects (class)
 I want to keep these three layers as independent as possible, so in future we make it Web based, my PL will only change. if we use SQL server instead of Access, only DAL will change. If we change business rules, only BLL will change.
I have been searching the net for last two days,but cannot find sample code for VB.NET AND Winforms, or simple enought to understand.
So the question is : how do I implement DA so that it passes class or list or array
How does the BLL pass this data to PL
, And in PL(form level) how do i populate Combobox(Dropdown List)  using it's datasource property? This combobox will have Category Name as display Item and Category_Id as tag(? )(Itemdata in vb6 world).

This will be my basic building block and from this, I can build more complicated routines.
I will greatly appreciate if you can provide me a small but complete sample code in vb.net. for Winforms . Thanks in advance.

I
0
Comment
Question by:RekhaShah
  • 11
  • 11
  • 5
27 Comments
 
LVL 18

Expert Comment

by:DarrenD
ID: 33689943
Hi,

The PL can be any client app such as web page, silverlight or winform.

The BL is where all the rules are stored

The DAL is what you use tyo access the database.

Your best way to make all of this work is to either use .NET Remoting, Web Services or WCF.

Personally I would use WCF. This would sit between PL and BL so the system would be as follows

PL <-> WCF <-> BL <-> DAL <-> Database(Access, SQL Server, Oracle)

You can host WCF services in IIS which is probably the easiest way to get started (IMO).

If you are only ever going to have .NET PL then I would use generic List(Of T) to pass objects (classes) back and forth. If you might have a Java PL then you would probably have to use normal arrays (as far as I'm aware).

To populate a Combo you can use

            cboStaff.DisplayMember = "FullName"
            cboStaff.ValueMember = "UserName"
            cboStaff.DataSource = _employees

_employees is this case id a List (Of Employee)

Here are some links

http://www.c-sharpcorner.com/Articles/ArticleListing.aspx?SectionID=1&SubSectionID=192

Hope this helps,

Darren
0
 
LVL 18

Expert Comment

by:DarrenD
ID: 33689957
Hi,

This is probably the easiest to get you started

http://www.c-sharpcorner.com/UploadFile/378f37/2577/

Cheers,

Darren
0
 
LVL 7

Expert Comment

by:klakkas
ID: 33690130
The way to go is the following:

In the DAL, create a ProductCategory Class and use this to return your Data to the BL. Example:

Public Class DAL

    Public Class ProductCategory
        Public ID As Integer
        Public Name As String
        Public Category As String

        Public Sub New(ByVal newID As Integer, ByVal newName As String, ByVal newCategory As String)
            ID = newID
            Name = newName
            Category = newCategory
        End Sub

        Public Sub New()

        End Sub


    End Class


    Public Shared Function GetProductCategories(ByVal Params As String) As List(Of ProductCategory)
        Dim Res As New List(Of ProductCategory)
        'Get the data from the DB
        Dim dt As DataTable = ExecSelectCmd("Select * from ProductCategories")

        'Populate the result
        For Each r As DataRow In dt.Rows
            Res.Add(New ProductCategory(r("Id"), r("Name"), r("Category")))
        Next

        'Return
        Return Res

    End Function

    Private Shared Function ExecSelectCmd(ByVal sSql As String) As DataTable
        Dim dt As DataTable
        'Go get the data from DB
        Return dt
    End Function

End Class

In the BL, you also need to re-create the ProductCategory Class, keeping in mind that this will be the one that the PL will be using. For this reason, you should probably use Properties instead of Public  variables and definitely Override the toString function. Example:

Public Class BL

    Public Class ProductCategory
        Public ID As Integer
        Public Name As String
        Public Category As String

        'If you want, you can set these parameters to Private and use Properties to expose them

        Public Sub New(ByVal newID As Integer, ByVal newName As String, ByVal newCategory As String)
            ID = newID
            Name = newName
            Category = newCategory
        End Sub

        Public Sub New()

        End Sub

        'Use this ToString Override, in order to have the object shown as you want in the combobox
        Public Overrides Function ToString() As String
            Return Name + " (" + Category + ")"
        End Function
    End Class

    Public Shared Function GetBL_Categories(ByVal Params As String) As List(Of ProductCategory)
        'Process the params

        Dim tempRes As List(Of DAL.ProductCategory) = DAL.GetProductCategories(Params)

        'Tricky Part: Convert the DAL.ProductCategory to BL.ProductCategory
        Dim Res As New List(Of BL.ProductCategory)
        For Each PC As DAL.ProductCategory In tempRes
            Res.Add(New BL.ProductCategory(PC.ID, PC.Name, PC.Category))
        Next

        'Do your business logic here


        Return Res
    End Function

End Class

Finally, in your PL (any type of it, WinForms, WebSite, etc) you can easily consume the BL result as follows:

Fill the combobox
ComboBox1.items.AddRange(BL.GetBL_Categories(myParams).toArray)
Remember that the text that will be visible for each item will be the result of the Overriden ToString function of the Class

Get the Selected ProductCategory
dim SelectedProd as BL.ProductCategory = ctype(ComboBox1.SelectedItem, BL.ProductCategory)

Let me know if any part of this needs more clarification
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

Author Comment

by:RekhaShah
ID: 33692401
you said,
    'If you want, you can set these parameters to Private and use Properties to expose them...
i created public properties with private variables like mn_CategoryName, mn_categoryID etc
How do you modify
Public Sub New(ByVal newID As Integer, ByVal newName As String, ByVal newCategory As String)
            ID = newID
            Name = newName
            Category = newCategory
        End Sub

        Public Sub New()

        End Sub
 to use properties insted of  public var ID, Name etc? Please bare with me, I amstrill trying to grasp the whle concept of Object oriented programming.
0
 
LVL 7

Expert Comment

by:klakkas
ID: 33692503
No need to modify anything...

Full class is the following:
Public Class ProductCategory
        Private mn_ID As Integer
        Private mn_Name As String
        Private mn_Category As String

        Public Property ID() As Integer
            Get
                Return mn_ID
            End Get
            Set(ByVal value As Integer)
                mn_ID = value
            End Set
        End Property

        Public Property Name() As String
            Get
                Return mn_Name
            End Get
            Set(ByVal value As String)
                mn_Name = value
            End Set
        End Property

        Public Property Category() As String
            Get
                Return mn_Category
            End Get
            Set(ByVal value As String)
                mn_Category = value
            End Set
        End Property
        
        Public Sub New(ByVal newID As Integer, ByVal newName As String, ByVal newCategory As String)
            ID = newID
            Name = newName
            Category = newCategory
        End Sub

        Public Sub New()

        End Sub

        'Use this ToString Override, in order to have the object shown as you want in the combobox
        Public Overrides Function ToString() As String
            Return Name + " (" + Category + ")"
        End Function
    End Class

Open in new window

0
 
LVL 7

Expert Comment

by:klakkas
ID: 33692529
The alternative would be to have the New Function write directly to the parameters, ex:

Public Sub New(ByVal newID As Integer, ByVal newName As String, ByVal newCategory As String)
            mn_ID = newID
            mn_Name = newName
            mn_Category = newCategory
        End Sub

But there is no need to do this, let the property do the writting.

Don't hesitate to ask if you need anything else.
0
 

Author Comment

by:RekhaShah
ID: 33692971
Thanks, Klakkas for your prompt reply. I will try to implement this and get back to you asap. So i don't need the following coe if i am using properties?
Public Sub New(ByVal newID As Integer, ByVal newName As String, ByVal newCategory As String)
            ID = newID
            Name = newName
            Category = newCategory
        End Sub

        Public Sub New()

        End Sub
 
Or do I use the following like you suggested in your code?
Public Sub New(ByVal newID As Integer, ByVal newName As String, ByVal newCategory As String)
            mn_ID = newID
            mn_Name = newName
            mn_Category = newCategory
        End Sub

        Public Sub New()

        End Sub
 

Why do i need an empty Sub New? and Why do I need Sub New with parameters?
 
0
 
LVL 7

Expert Comment

by:klakkas
ID: 33693040
If you don't declare any Sub New, an empty one is created automatically.

If you do declare a Sub New with parameters, the empty one is not created automatically, you should create it manually.

Now, regarding the need for them, it is simple: Having a new with parameters allows you to declare the object in one single line:
       dim Obj as New ProductCategory(5,"Kyriakos","Developer").
Without it, you would need 4 lines:
       dim Obj as new ProductCategory
       Obj.ID = 5
       Obj.Name = "Kyriakos"
       Obj.Category = "Developer"

It is simply a matter of writting less code...
0
 
LVL 7

Expert Comment

by:klakkas
ID: 33693069
Oh, and regarding the 2 versions of the Sub New with parameters, I suggest using the first one, which uses the Properties to update the variables.

Public Sub New(ByVal newID As Integer, ByVal newName As String, ByVal newCategory As String)
           ID = newID
           Name = newName
           Category = newCategory
       End Sub

0
 
LVL 18

Expert Comment

by:DarrenD
ID: 33693652
You could also do the following:

      Public Sub New(ByRef obj as ProductCategory)
           ID = obj .newID
           Name = obj .newName
           Category = obj .newCategory
       End Sub

and this should be quicker as you do not have to make a call to the property.

      Public Sub New(ByRef obj as ProductCategory)
           mn_ID = obj .newID
           mn_Name  = obj .newName
           mn_Category  = obj .newCategory
       End Sub

Darren
0
 

Author Comment

by:RekhaShah
ID: 33693662
Thank you very much. It worked like a charm!
I really don't know what would I do without you guys out there willing to help! This is exactly what I needed.
Last question :
I still wonder, Why do I have to repeat properties in BLL and DA layers?  If I need to modify/add,delete any of the properties, I have to maintain at two places. This was a simple example, but when i have about 50 prioperties of an object, would i follow the same logic/Pattern? Can I have a Category class, define all the properties and inherit that class in both DA and BLL layers? If I can, how would I?
0
 
LVL 18

Expert Comment

by:DarrenD
ID: 33693663
Should be

      Public Sub New(ByRef obj as ProductCategory)
           mn_ID = obj .ID
           mn_Name  = obj .Name
           mn_Category  = obj .Category
       End Sub
0
 
LVL 18

Expert Comment

by:DarrenD
ID: 33693714
Hi,

The fact is that you should not really be just reiterating code. For example if you had about 50 properties then you should only be sending the ones that you need for the piece of functionality. For this I would create a smaller class which would be the subset that you needed and send these down to the client instead of the entire 50.

Also in the database you may have a list of values such
1 = EURO
2 = STERLING
3 = USD

If you stored the record in the database as an int then you can convert the int into the string value in the business layer so that the PL does not have to know how to convert 1 to EURO.

Cheers,

Darren
0
 

Author Comment

by:RekhaShah
ID: 33693786
I have three directories in my project PL: has all the forms .BLL has all the business logic for each of my objects like ProductCategory,Customer, Vendor etc. DA has all the corrresponding DA routines. i alsohave onc commoneDA file that has allt he excuete,openConn, closeConn etc routines.
If I define a new class call  " Product" , and all it has is all the properties like name, id,category etc. This will be  in another folder. right? And in business layer s well as DA layer, I will just declare this Product call as local object and go forward like Klakkas suggested?
Can you give me a detail sample code please?
0
 
LVL 7

Expert Comment

by:klakkas
ID: 33699297
If you want to go like this, then you should build a DLL with all your objects (products, Customers, etc) and declare their Classes, Properties, ToString Overrides, etc there.

Having done that, this DLL should be referenced from all 3 layers of your application, so that the can communicate using these classes.

Assuming that the DLL is named ObjDeclaration, the code should look like this :

DLL:
Public Class ObjDeclaration
    'Declare all your parameters, properties, Functions, New constructors, ToString Overrides, etc
End Class

DAL (Declaration only, the code remains the same):
 Public Shared Function GetProductCategories(ByVal Params As String) As List(Of ObjDeclaration.ProductCategory)

BL:
Public Shared Function GetBL_Categories(ByVal Params As String) As List(Of ObjDeclaration.ProductCategory)

        Dim Res As List(Of ObjDeclaration.ProductCategory) = DAL.GetProductCategories(Params)
       
        'Business logic here

        Return Res
End Function

PL:
Fill the combobox
ComboBox1.items.AddRange(BL.GetBL_Categories(myParams).toArray)

Get the Selected ProductCategory
dim SelectedProd as BL.ProductCategory = ctype(ComboBox1.SelectedItem, ObjDeclaration.ProductCategory)

As you can see, the layers use ObjDeclaration.ProductCategory to communicate. The only drawback is that the DAL is not completely independant from the rest of the application, since it relies on the common ObjDeclaration DLL.

0
 

Author Comment

by:RekhaShah
ID: 33700855
Would you recommand that I take this route(wigh DLL)   or just  do it the way you suggested  in the first place?  i am going to build one object the right way. and then just dopy and paste the rest of the objects in the system. So I would rather spend more time upfront and do it the right way. Due to my inexperience, I need your advice.
Actually, I am converting a vb6 application that goes thru lot of changes (adding more objects, changing rules, changing database etc). My 90% of the time is spent in maintaining the app, if i fix one thing, it will break 10 more. My boss agreed to let me rewrite this app, so i better do it right :)
0
 
LVL 7

Expert Comment

by:klakkas
ID: 33700922
Personally, I would go with the ObjectDeclaration DLL, especially since you are working with a small team.

Just make sure you declare the Objects very carefully from the start, because if for example (some time in the future) you need one extra field for the BL, you with have to rebuild the DAL as well (since the referenced DLL will have change).

Good luck!
0
 

Author Comment

by:RekhaShah
ID: 33701020
Ok, i will build ObjectDeclaration DLL.
Like I mentioned earlier,  all BLL, PL and DA are just the folders in my single project solution. so when I make changes to the DLL, I will be building my project any way so, it will affect all the layers. right? Or would you recommand, I have three different projects - BLL,PL and DA  of the same solution?
i am a one member team who wares all the hats.
0
 
LVL 7

Accepted Solution

by:
klakkas earned 2000 total points
ID: 33701290
Seperate projects, definitely seperate projects.

DAL, BLL and ObjectDeclarations as DLLs and the PL as widnows Application.

This way, when you want to create a web site, you create the ASP project and add the 3 references.

Further, if in the future you want to change your DAL to talk (for example) with Oracle, and you have a collegue who is willing to help you, you only give him the DAL, not your entire code.
0
 

Author Closing Comment

by:RekhaShah
ID: 33702160
Thank you very much for all your help. i have much clearer idea about the objects.
0
 

Author Comment

by:RekhaShah
ID: 33702175
Sepearate DLL for each object  but one project. right?
0
 
LVL 7

Expert Comment

by:klakkas
ID: 33715046
Hello RekhaShah,

sorry for the delay, but I don't work on weekends! :-)

Each DLL is a different project. All the projects are under the same solution.

So, when you will actually deploy the application to a customer, you will install (at least) 1 exe and 3 dll files.
0
 

Author Comment

by:RekhaShah
ID: 33715910
"..but I don't work on weekends! :-) "
Lucky you!!

 I am very thankful to  you. Like I mentioned earlier, it is a very complex project  with lots of objects. Is  there a reason, why each object should be embedded in its on project? This is a desktop app with .mdb file. Sure, I am looking for scalability,  but does it have  to be composed of so many dlls?
0
 
LVL 7

Expert Comment

by:klakkas
ID: 33715979
If you want to "simplify" it, you could merge DAL, BLL and ObjectDefinition in one DLL project and the Windows Forms App in a different project. Of course, both projects will be under the same solution. Just remember that only the BLL and ObjDef classes will be public, the DAL will be private.

I insist on the DLL, because if you want to create a WebSite for this work, alll you will have to do is add this DLL to the WebSite project (no source code).

0
 

Author Comment

by:RekhaShah
ID: 33716103
I got it (I think) .. thanks. So I will have the following in my Solution:

dll for each of my objects - customer, product,category etc with its properties  . I will reference them in my solution

a BLL  project with separate class for each object e.g.  BLL_customer.cls, BLL_Products.cls etc

A DA Project with all the classes for each objects with getters and setters .e.g. DA_Products.cls, DA_Category.cls and so  on.

And the easiest layer :PL with all my forms ( I am looking into WPF also).

Am I in the right direction?


0
 
LVL 7

Expert Comment

by:klakkas
ID: 33716326
No, no, you missunderstood me!

1 single ObjDef.dll with ALL the objects Definition. Each object is a different class file in the project.

1 DAL.dll which has reference to ObjDef.dll and uses these classes to return data.

1 BLL.dll which has reference to ObjDef.dll and DAL.dll and uses the objDef classes to return data.

1 windows forms application, which has reference to BLL.dll. I am not if you also must reference ObjDef.dll in your .exe project.

A total of 1 exe and 3 dll files.
0
 

Author Comment

by:RekhaShah
ID: 33718933
I finally got it!  Dhu...
Yes, I was wondering about having separate dll for each object :(
Thank you very much for clarifying.

I am on my way to OOP!
0

Featured Post

NFR key for Veeam Agent for Linux

Veeam is happy to provide a free NFR license for one year.  It allows for the non‑production use and valid for five workstations and two servers. Veeam Agent for Linux is a simple backup tool for your Linux installations, both on‑premises and in the public cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

If you need a simple but flexible process for maintaining an audit trail of who created, edited, or deleted data from a table, or multiple tables, and you can do all of your work from within a form, this simple Audit Log will work for you.
Explore the ways to Unlock VBA Project Password Excel 2010 & 2013 documents. Go through the article and perform the steps carefully to remove VBA Excel .xls file.
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…
Have you created a query with information for a calendar? ... and then, abra-cadabra, the calendar is done?! I am going to show you how to make that happen. Visualize your data!  ... really see it To use the code to create a calendar from a q…

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question