locked
Business and DAL Layer Interaction Question RRS feed

  • Question

  • User-503940700 posted

    Hello People,

    Sometime back I was wrking on a project whose BL layer used to talk with DAL using DAL DTOs.

    There I noticed that the BL objects never had any private members but used the DTO itself.

    Eg.: there is a Customer class with 3 attributes.

    now, when thinking of using DTOs, my approach is like:

    class Customer
    { private string _name;
    private int _age;
    private int _id;

    public Customer() {} //public constructor
    internal Customer(customerDTO data)
    {
      _name = data.Name;
      _age  = data.Age;
      _id   = data.Id;
    }

    public string Name
    {
    //return this._name;
    }

    //similary properties for each private attribute that needs to be exposed.
    }

    Now, in CustomerList class i will have some method FindCustomers(criteria) which will return a list of CustomerDTOs. I will then instantiate a new Customer object passing that DTO in the constructor.

    But in that project, I noticed different behaviour. The DTO was passed in the Customer objects constructor but the code was like:

    class Customer
    {
      private CustomerDTO _data;  //no other private attributes
     
      internal Customer(CustomerDTo data)
       {
          this._data = data;
       }

       public string Name
     {
      return _data.Name;
      }

    //similarly other properties
    }

    Now, i think that this approach isnt right as BL is now more tightly coupled with the

    DAL DTOs. Its like intead of the BL defining the attributes, the job is upto the DTO.  Am i right?

    vivek

    Sunday, July 30, 2006 10:17 AM

All replies

  • User-1929628483 posted
    >>>Its like intead of the BL defining the attributes, the job is upto the DTO.  Am i right?

    OO paradigm is package data + behavior but in most of the cases u should not worry too much.There is not right or wrong way while coding this staff.

    U can either use DTO or BL to define your attributes(and the attributeTypes) but u even can do it without defining it.... :)

    So if ı were u I would take the simplest way that will not bring pain today and also tomorrow.
    Sunday, July 30, 2006 3:15 PM
  • User-503940700 posted

    Hi,

    Thanks for your reply! But suppose if I let my DTO define the attributes, then my BL is tightly coupled with those DTOs. Assume a case when I am selling my BL independently, or some other DAL is consuming by BL.In such case, I *have to* include the DTOs also, which I dont like.

    Or take another case when some GUI wants to use my BL but not my DAL-BL DTOs. But I cant do so as my BL is "empty" without those DTOs. Note that DAL DTOs are different from DTOs interacting with BL and GUI (or some service interface).

    Let me know your comments on these.

    Thanks

    Vivek

    Sunday, July 30, 2006 3:24 PM
  • User438956265 posted

    Hi Vivek,

    If you want to take the responsibility of populating the business object state out from the business object , that is fine. In some ways, I think that it is better approach. You can have a service that takes buinsess object and DTO as parameters and using reflection APIs populate the state of business object from DTO.

    This way , you can reduce the number of lines of codes and your business object is independent of DTO.

    Martin Fowler  has a similar recommendation on DTO

    http://www.martinfowler.com/eaaCatalog/dataTransferObject.html

     

    Here is my post on identical archtiecture

    http://vikasnetdev.blogspot.com/2006/07/soa-friendly-architecture-version-of.html

     

    Hope  this helps

    Vikas

    Sunday, July 30, 2006 11:03 PM
  • User-503940700 posted

    Hi Vikas,

    I think I did not get your answer. Actually, let me explain.

    Martin's post on DTOs (in the link) does not talk anything about using DTOs inside BOs and replacing BO entities. Infact if you read his book (Patterns of Enterprise Application Architecture), you will find that he advises BL to be independent of DTOs. I have reproduced the text here:

    "..Nor do I want the domain objects to be dependent of the Data Transfer Object since the Data Transfer Object structure will change when I alter interface formats. As a general rule, I want to keep the domain model independent of the external interfaces."

    So he advises of a spearate assemblerobject here which takes care of DTO-BO mapping.

    So if we dont have this mapper and let DTOs carry business atributes, then how can the web service use some mapper to populate business objects fields (when there arent any if we use DTOs as a member of the business class:see my code example)?

    My answer is: we *have* to use a mapper and the business class will have all attributes related to business logic even if they are repeated in the DTO. But the other code sample is not doing this, which is wrong according to me. Hence my post.

    Let me know what you think.

    Regards,

    Vivek

    Monday, July 31, 2006 2:51 PM
  • User438956265 posted

    So if we dont have this mapper and let DTOs carry business atributes, then how can the web service use some mapper to populate business objects fields (when there arent any if we use DTOs as a member of the business class:see my code example)?

     

    My answer is: we *have* to use a mapper and the business class will have all attributes related to business logic even if they are repeated in the DTO. But the other code sample is not doing this, which is wrong according to me. Hence my post.

    Let me know what you think.

    Hi Vivek

    In architecture that I demonstrated, you don't need the DTO layer at all. It takes advantage of Web Service Capabilities of sending proxy objects (derived from real Business Objects) over the wire. It will be responsibility of Gateway Layer to provide the mapper to copy proxy objects data into real business objects.<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p>

    Right now my sample does not include mapper. Very soon, I am going to add mapper to Gateway /Factory Layer. Stay tuned

    I agree hundred percent with your analysis.

    Best of luck,

    Vikas

    Monday, July 31, 2006 3:40 PM
  • User438956265 posted

    Hi Vivek,

    Finally I have added a simple Mapper to my sample application architecture. Gateway/Factory Layer is making use of Mapper to convert the proxy objects sent over web service wire to real objects.

    http://vikasnetdev.blogspot.com/2006/07/soa-friendly-architecture-version-of.html

    http://vikasnetdev.blogspot.com/2006/07/soa-friendly-architecture-version-of_25.html

     

    Best of luck ,

    Vikas

     

    Mapper Code

    using System.Collections;

    using System.Reflection;

    using System;

    namespace Gateway

    {

    public abstract class Mapper

    {

    public static object MapProperties_Fields(object SourceObj, Type DestinationType)

    {

    if (SourceObj == null)

    {

    return null;

    }

    Type sourceType = SourceObj.GetType();

    object destinationObj = Activator.CreateInstance(DestinationType);

    foreach (PropertyInfo sourceProperty in sourceType.GetProperties())

    {

    MemberInfo destinationMember = DestinationType.GetMember(sourceProperty.Name)[0];

    if (destinationMember.MemberType == MemberTypes.Property)

    {

    PropertyInfo destinationProperty = ((PropertyInfo)(destinationMember));

    if ((destinationProperty.CanWrite == true))

    {

    if (destinationProperty.PropertyType.Equals(sourceProperty.PropertyType))

    {

    destinationProperty.SetValue(destinationObj, sourceProperty.GetValue(SourceObj, null), null);

    }

    }

    }

    }

    return destinationObj;

    }

    public static IList MapProperties_Fields(IList SourceList, Type DestinationListType, Type DestinationElementType)

    {

    if (SourceList == null)

    {

    return null;

    }

    IList destinationList = ((IList)(Activator.CreateInstance(DestinationListType)));

    foreach (object sourceObj in SourceList)

    {

    destinationList.Add(MapProperties_Fields(sourceObj, DestinationElementType));

    }

    return destinationList;

    }

    }

    }

     

     

     

    Monday, August 7, 2006 4:23 PM
  • User-503940700 posted

    Hi Vikas,

    Nice work!

    But my only worry is performace hit while using reflection :-(. But that depends on the business needs and might become insignificant issue if physical distribution and a high degree of loose coupling is required.

    I am also thinking of a simple code generator too. Anyways, have you heard of CSLA.NET?

    -Vivek

    Wednesday, August 9, 2006 1:57 PM
  • User438956265 posted

    But my only worry is performace hit while using reflection :-(. But that depends on the business needs and might become insignificant issue if physical distribution and a high degree of loose coupling is required. 

    It would be very minor(1 to 2 ms) as compared performance hit introduced by physical distribution and Database Access. It could potentially save you hundreds  if not thousands line of code.

    I am also thinking of a simple code generator too.

     

    Cannot disagree with this one. Excellent idea.

    Anyways, have you heard of CSLA.NET?

    I do follow very closely Rockford Lhotka's work(Books,articles,CSLA,blog) and his thoughts on technical issues.

    I have used his framework(starting from VB5.0) in some form in my some projects.

    What thoughts/questions do  you have about CSLA.Net?

     

    Vikas

    Thursday, August 10, 2006 9:05 AM