none
Layers Design in an N Tiered Architecture RRS feed

  • Question

  • Hello Friends,

     

    I would like to know your feedback/comments on following layers that we have designed in our project.

     

    (1) Business Entity Layer:

    ----------------------------------------------------------------------------

     

    public class Customer

    {

    string _Name;

    string _Id;

    string _Type;

    public string Name

    {

    get { return _Name; }

    set { _Name= value; }

    }

    public string Id

    {

    get { return _Id; }

    set { _Id= value; }

    }

    public string Type

    {

    get { return _Type; }

    set { _Type= value; }

    }

    }

     

    public class Customers: List<Customer>

    {

    }

    ----------------------------------------------------------------------------

    (2) Business Logic Layer:

     

    public class CustomerService

    {

    public Customer GetCustomerByID(int id)

    {

    return CustomerDalc.GetCustomerByID(id);

    }

    public Customers GetAllCustomers()

    {

    return CustomerDalc.GetAllCustomers();

    }

     

    }

    ------------------------------------------------------------------------------------

    (3) Data Acess Layer:

     

    public static class CustomerDalc

    {

    public static Customers GetAllCustomers ()

    {

    string storedProcedureName = "USP_Select_All_Customers";

    ArrayList parameters = new ArrayList();

    DataTable dt = DatabaseHelper.ExecuteQuery(storedProcedureName, parameters);

    Customers custs = new Customers();

    foreach (DataRow dr in dt.Rows)

    {

    custs .Add(MakeCustomer(dr));

    }

    return custs ;

    }

     

    static public Customer MakeCustomer(DataRow row)

    {

    Customer Cust= new Customer();

    Cust.ID = int.Parse(row["cust_id"].ToString());

    Cust.Name= row["cust_name"].ToString();

    return Cust;

    }

    }

     

     

    ------------------------------------------------------------------------------------

    (4) Presentation Layer:

     

    private void btnViewAllCustomers_Click(object sender, EventArgs e)

    {

    CustomerService _service = new CustomerService ();

    this.dgrdCustomers.DataSource=this._service.GetAllCustomers();

    }

     

     

    I would also like to know about data grid binding at prensentation layer , should we return a datatable from CustomerService.GetAllCustomers() method to bind into datagrid or above collection is fine.

     

    Please let me know your comments on above layers design.

     

    Regards,

     

    David


     

    Wednesday, June 11, 2008 10:15 AM

All replies

  • Personally, i don't see why the presentation layer would not be allowed to know about the business entities...

    If i understand well, your business logic is tightly coupled to your data access layer (presuming you have a reference to it in the projet file.), which isn't a good thing imho.
    Wednesday, June 11, 2008 12:32 PM
  •  

    Hi Tim,

     

    Thanks for chipping in this thread. As per your experiance could you please share us layer's architecture that is secure enough as well as easy to maintenence.

     

    Regards,

    David

     

    Wednesday, June 11, 2008 12:45 PM
  •  

    David,

    I think your layers are good. Also, I don't think you should pass datatable instance from the lower layers to your presentation layer. Passing a datatable not only hides the actual data types and contents but also it makes the developer's life harder as you have to cast every time you use some data from the datatable.

     

    Thanks,

    Sohan

    http://smsohan.blogspot.com

    Thursday, June 12, 2008 3:37 AM
  • I would define a contract between data access and bussiness logic.. And then inject the dac instances.. This way the hard coupling vanishes...
    Thursday, June 12, 2008 6:56 AM
  •  timvw wrote:
    I would define a contract between data access and bussiness logic.. And then inject the dac instances.. This way the hard coupling vanishes...

     

     

    Tim:

     

    Can you please explain on more this? Especially on "And then inject the dac instances".

    An example would be great.

     

    My understanding is that you are recommending to create an interface ICustomerDalc and then the BLL would use the interface to interact with the CustomerDalc object. Am i right?

     

     

     

    Thursday, June 12, 2008 5:58 PM
  • Hi Tim,

     

    As per you the layers would like following or you have something different. Would appreciate if you could elaborate your design approach.

     

    (1) Business Entity Layer:

    ----------------------------------------------------------------------------

     

    public class Customer

    {

    string _Name;

    string _Id;

    string _Type;

    public string Name

    {

    get { return _Name; }

    set { _Name= value; }

    }

    public string Id

    {

    get { return _Id; }

    set { _Id= value; }

    }

    public string Type

    {

    get { return _Type; }

    set { _Type= value; }

    }

    }

     

    public class Customers: List<Customer>

    {

    }

     

    public interface ICustomerService

    {

    void CreateCustomer(Customer Cust);

    void UpdateCustomer(Customer Cust);

    void DeleteCustomer(Customer Cust);

    }

     

    ----------------------------------------------------------------------------

    (2) Business Logic Layer:

     

    public class CustomerService : ICustomerService

    {

    public Customer GetCustomerByID(int id)

    {

    return CustomerDalc.GetCustomerByID(id);

    }

    public Customers GetAllCustomers()

    {

    return CustomerDalc.GetAllCustomers();

    }

     

    //Interface members

     

    public void CreateCustomer(Customer Cust)

    {

    CustomerDalc.CreateCustomerRecord(Cust);

    }

    public void UpdateCustomer(Customer Cust)

    {

    CustomerDalc.UpdateCustomerRecord(Cust);

    }

    public void DeleteCustomer(Customer Cust)

    {

    CustomerDalc.DeleteCustomerRecord(Cust);

    }

    }

    ------------------------------------------------------------------------------------

    (3) Data Acess Layer:

     

    public static class CustomerDalc

    {

    public static Customers GetAllCustomers ()

    {

    string storedProcedureName = "USP_Select_All_Customers";

    ArrayList parameters = new ArrayList();

    DataTable dt = DatabaseHelper.ExecuteQuery(storedProcedureName, parameters);

    Customers custs = new Customers();

    foreach (DataRow dr in dt.Rows)

    {

    custs .Add(MakeCustomer(dr));

    }

    return custs ;

    }

     

    static public Customer MakeCustomer(DataRow row)

    {

    Customer Cust= new Customer();

    Cust.ID = int.Parse(row["cust_id"].ToString());

    Cust.Name= row["cust_name"].ToString();

    return Cust;

    }

     

    // CRUD methods would be here......

    }

     

     

    ------------------------------------------------------------------------------------

    (4) Presentation Layer:

     

    private void btnViewAllCustomers_Click(object sender, EventArgs e)

    {

    CustomerService _service = new CustomerService ();

    this.dgrdCustomers.DataSource=this._service.GetAllCustomers();

    }

     

    Thanks & Reagrds,

     

     

    Friday, June 13, 2008 4:51 AM
  • I usually consider Business Entities (BE) & Business Services (BS) as one part, and in situations when they are rather large, i try to separate them in separate components (thus splitting up horizontally instead of vertically). Eg: BusinessPartyComponent (to manage parties we do business with) and ContractComponent (to manage contracts we have).


    For me the problem is that your Business Services are tightly coupled to your DAC. I would define an interface IDAC and then program against that interface in the BS, probably by adding a Repository class in the BS (which then uses dependency injection to acquire an implementation of the IDAC.)
    Friday, June 13, 2008 6:21 AM