9

I did some research before posting this question. Among other questions or post, one of those is provided below. I could not get a clear mind how to determine..

Business Objects within a Data Access Layer

I have a Repository and the Business Layers call the repository to retrieve the data. For example, say I have the following classes for BLL and DAL:

class BllCustomer
{
    public int CustomerId {get; set;}
    public String Name {get; set;}
    public BllAddress Address {get; set;}
}

class BllAddress
{
     public int AddressId {get; set;}
     public String Street {get; set;}
     public String City {get; set;}
     public String ZipCode {get; set; }
}

class DalCustomer 
{
    public int CustomerId {get; set;}
    public String Name {get; set;}
    public int AddressID {get; set;}
}

class DalAddress
{
     public int AddressId {get; set;}
     public String Street {get; set;}
     public String City {get; set;}
     public String ZipCode {get; set; }
}

If the BLL wants to retrieve a Customer object, it would call GetCustomerById(customerId) in DAL.

The following are my concerns I could not get a clear mind:

  1. I cannot see how to determine what object the GetCustomerById in DAL should return? Should it return BllCustomer or DalCustomer?

  2. Where should be the retrieving (and/or converting to Business object) of the address associated with the customer?

If the DAL returns Dal objects then, the logic to retrieve and fill in the Address can only be in the BLL. If the DAL returns BLL objects, then the logic to retrieve and fill in the Address can be either in the BLL or DAL. Currently the DAL is returning the Business Objects and the logic to fill it in is in the DAL.

From what I read, I guess there is no right or wrong. From the link included above, there are people saying one way and the others are saying the other way. But how do I determine which would works best for my case?

Any help would be appreciated.

  • 2
    My first question would be: is this a legacy application? There are plenty of ORM Frameworks out there that make this kind of code obsolete and I would urge you to consider such a framework... – JDT Jan 30 '15 at 15:08
  • @JDT I'm not sure what you mean, I am using Entity Framework and having the exact same problem. As I understand it, you're not supposed to use your ORM as domain objects, so where is the translation made? – pseudocoder Nov 6 '15 at 15:11
  • Why would your ORM framework not return objects that are domain objects as well? – JDT Nov 6 '15 at 15:15
  • 2
    @JDT The ORM (EF in this case) returns entity classes that represent, typically, one database table per class. This is usually similar to, but not necessarily the same as, the domain classes. Maybe you are just saying that it is ok to use ORM classes as domain classes? I have read in a number of places that this is a no-no. – pseudocoder Nov 6 '15 at 15:30
5

I cannot see how to determine what object the GetCustomerById in DAL should return? Should it return BllCustomer or DalCustomer?

It should return a DalCustomer object, returning a BllCustomer object will break the single-responsibility principle. You can view the DalCustomer object as the interface or contract consumed by the business layer (or consumer). In effect if it returned a BllCustomer the DAL would have to cater for every business layer object that calls it or could potentially call it.

Where should be the retrieving (and/or converting to Business object) of the address associated with the customer?

The conversion should be done in a view model or manager. You need to have a intermediary to call your service or data access component. If you feel the need you can have a conversion in your BllCustomer object. But then when you swap your DAL from MSSQL to Oracle for example your returned object (or interface) must remain the same.

Preferably your business layer should also be independent of your Data Layer. The Business Layer is responsible for your business rules. It is here you will add your validations using a validation framework to enforce your business rules.

3

Typically, the DAL has no knowledge of the BLL. Think of it this way, a different application with a different BLL could use the same DAL. A Payables application/module and a Receivables app for the same company would share data (clients, charges, payments, etc.). Trying to have one DLL have knowledge of more than one BLL would be very difficult and unnecessary. This would also allow you to change your data storage with no impact on the BLL (as long as you don't break the interfaces).

You now can pass a DAL object to the BLL or you could create a third set of objects: Entity. These would contain just the values to be passed around together. The DAL would reference the entity and interact with your storage/database and the BLL would handle all the logic and reference the DAL.

class EntCustomer
{
    public int CustomerId {get; set;}
    public String Name {get; set;}
    public BllAddress Address {get; set;}
}
class BllCustomer
{
   //reference EntCustomer, DalCustomer and handle business rules/logic
}

class DalCustomer 
{
   //reference EntCustomer and interact with data storage
}
  • Thank you for your comment. I agree with you.. I can already see that our DAL/(Repository) is already filled with logics like if the type is A, then go retrieve data from table B, but if the type is C,then go retrieve data from table C. But I am confused with your example using EntCustomer. In my case, DalCustomer is mirror of the tables in DB. Can you provide more examples, how the EntCustomer is used or why I should used it and benefits of it.I'm thinking to change DAL to return DalObjects to the BLL. Bll will hangle conversion to Business Objs,retrieve and fill in nested obj. – ShamirDaj Nov 2 '14 at 5:09
  • Can you provide more feedback? – ShamirDaj Nov 3 '14 at 4:38
  • I think that the purpose of the Ent-objects is to just transfer data between DAL and BLL. Your DAL classes can continue to mirror the db structure, but those classes would be internal to DAL. When the BLL asks for data from DAL, the DAL would fetch the required DAL-objects from the database (dalcustomer + daladdress) and construct an instance of EntCustomer from them and return it to BLL. – artokai Nov 3 '14 at 19:37
3

Your repository should return the BLL or domain object. chances are you don't need a DAL object at all.

public class Customer
{
    public string Name {get; private set;}
    public Customer(string name)
    {
        this.Name = name;
    }
}

public class Repository
{
    public Customer GetCustomer(string id)
    {
        //get data from db
        return new Customer(datarow["name"]);
    }
}
-1

DAL should be independent from BL and BL dependent on DAL. Your UI should only Access data via BL. Its good practice if you return DataTable or DataRow from DAL and then Convert DataTable/DataRow into BL object(s). When your UI needs to access the data it can access from BL. So UI will independent from column name and Database type(SQL Server, Oracle..). This way your UI will totally independent from DAL. Personally I prefer class name like "CustomerBL", Don't use the BL word in the begging of class name.

Below see Sample Code.

//Customer Class
class BllCustomer
{
    public int CustomerId { get; set; }
    public String Name { get; set; }
    public BllAddress Address { get; set; }

    public static BllCustomer GetByCustomerId(int id)
    {
        DataRow dr = DalCustomer.GetByCustomerId(id);
        if (dr == null)
            return null;
        BllCustomer oCust = new BllCustomer();
        oCust.CustomerId = int.Parse(dr["CustomerId"].ToString());
        //Do for other class members and load values

        return oCust;
    }
}


class DalCustomer
{

    public static DataRow GetByCustomerId(int id)
    {
        //Get Data row from Database and return Datarow
        DataRow CustomerRow = GETFROMDATABASE("SELECT * from CUSTOMER");
        return CustomerRow;
    }
}
  • Err... Doesn't that then mean that your BLL needs to have knowledge of the format/structure of your data tables?... – Paul Jul 21 '17 at 9:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.