locked
Passing Parameters between layers RRS feed

  • Question

  • My n-tier application looks like that
    ----------------------------------------------------
    Presentation Layer
    Business Logic Layer
    Data Access Layer
    Common folder

    Just wondering what is a better way to pass parameters between layers.  It's kind of trouble if I have 10+ parameters in a single method.

    Please help ~

    Wednesday, July 18, 2012 10:04 AM

Answers

  • It depends on the object type. But your object looks like a poco, which is not a business object. A poco is a DTO, a Data Transfer Object.

    Now for the naming: Using Object is a fail. It's a keyword, and should never be used as name. As the DTO's are used in every layer, you can consider it to be a column instead. I would place it in a namespace either called Common or DataTransferObject:

    namespace MyApplication.Common
    {
        public abstract class BaseDataTransferObject {}
    
        public class Category 
          : BaseDataTransferObject 
        {
            public int CategoryID { get; set; }
            public string CategoryName { get; set; }
        }
    }
    I would also use always the language data types, thus string instead of String. Also don't use two different data types for private field and its property accessor (int <> Int32). When there is no special property access handling the I prefer auto-implemented properties. Also use a base class, which implements the basic operations of your DTO. This includes especially the GetHashCode() method and often the ToString() method.


    • Marked as answer by Lisa Zhu Wednesday, July 25, 2012 9:52 AM
    Thursday, July 19, 2012 7:40 AM
  • I would and often do take a different approach than Stefan recommends using the Visitor Pattern which simply entails events! I prefer event based programming because to me it is the best for "Separation of Concerns"  the main idea being that the sender could care less who the listeners are!  This is a very important concept for "Loose Coupling" as it is the absolute best way to support asynchronous techniques which include Parralel programming.  This means that you can build lighting fast applications centered around an event based model.

    //Step 1 Create a class and name it 'Delegates.cs', remove all the code but just keep the namespace declaration and put in the delegate signatures like this public delegate void OnNewCustomer(ObservableCollection<Customer>); //Step 2 in the class that notifies everyone that there's new data, create a static event... public static event OnNewCustomer GotNewData; //in the logic that gets the data and needs to tell listeners, do this var MyCustomerCollection = new ObservableCollection<Customer>(); MyCustomerCollection = GetCustomerData();

    //Do the notification if(GotNewData!=Null){ GotNewData(MyCustomerCollection);


    And you can get tricky with this as well by doing what Stefan recommended you can pass Actions and or Functions as event parameters as well.  But for now just focus on passing the data over to a registerd listener.


    JP Cowboy Coders Unite!


    • Edited by Mr. Javaman II Thursday, July 19, 2012 12:43 PM
    • Marked as answer by Lisa Zhu Wednesday, July 25, 2012 9:55 AM
    Thursday, July 19, 2012 12:41 PM

All replies

  • As general approach: Use poco's to carry the data, then you can pass parameters as lambda expressions on your poco's from layer to layer

    But this is not a good OOP way to do it. What method requires 10 or more parameters? This makes no sense in most cases. Sounds like you should take a look at overloading your methods.

    Consider using the facade pattern between presentation and business layer.

    Wednesday, July 18, 2012 10:26 AM
  • Please think of it like "Passing Data between Layers", thanks ~
    Wednesday, July 18, 2012 10:33 AM
  • Just create an object and pass ONE object with it's properties.

     

    Noam B.



    Do not Forget to Vote as Answer/Helpful, please. It encourages us to help you...

    • Proposed as answer by Joon84 Wednesday, July 18, 2012 11:30 AM
    Wednesday, July 18, 2012 10:49 AM
  • You could also create a class in your common bin folder (assuming that this library is referenced in all of your other layers), and pass the data that way. Below is a free-wrote example done in notepad... it should only be used as an example and may contain errors.

    example:

    // Common Bin Class
    namespace Common
    {
        public class DatabaseObject
        {
            Boolean _Success;
            string _Data;

            public DatabaseObject()
            {
                this._Data = string.Empty;
                this._Success = false;
            }

            public string Data
            {
                get { return _Data; }
                set { _Data = value; }
            }

            public Boolean Success
            {
                get { return _Success; }
                set { _Success = value; }
            }
        }
    }

    // DAL
    namespace DataAccess
    {
        public class DAL
        {
            public DAL() { }

            public static void RandomDatabaseTask(DatabaseObject _DataObject)
            {
                if (_DataObject.Success) { Something1 = _DataObject.Data; }
            }
        }
    }

    // BAL
    namespace BusinessAccess
    {
        public class BAL
        {
            public BAL() { }

            public static void RandomDatabaseTask()
            {
                DatabaseObject _DataObject = new DatabaseObject();
       
       _DataObject.Success = true;
       _DataObject.Data = "Some Random Text";
       
       BAL.RandomDatabaseTask(_DataObject);
            }
        }
    }

    Wednesday, July 18, 2012 11:29 AM
  • Here below is the sample coding in my application

    namespace MyApplication.Object
    {
        public class Category
        {
            private int m_categoryID;
            private string m_categoryName;

            public Int32 CategoryID
            {
                get { return m_categoryID; }
                set { m_categoryID = value; }
            }

            public string CategoryName
            {
                get { return m_categoryName; }
                set { m_categoryName = value; }
            }

        }
    }

    My Questions:
    --------------------------------------------------------------
    1. I prefer to have a folder to contain all these files, I see somebody used "Objects", "Value Objects", or even "Business Objects", which one is more common in software industry?

    2.  For the class name like "public class Category", do I need to include the object name like "public class CategoryObject" ?

    Please advice ~~

    Thursday, July 19, 2012 6:50 AM
  • It depends on the object type. But your object looks like a poco, which is not a business object. A poco is a DTO, a Data Transfer Object.

    Now for the naming: Using Object is a fail. It's a keyword, and should never be used as name. As the DTO's are used in every layer, you can consider it to be a column instead. I would place it in a namespace either called Common or DataTransferObject:

    namespace MyApplication.Common
    {
        public abstract class BaseDataTransferObject {}
    
        public class Category 
          : BaseDataTransferObject 
        {
            public int CategoryID { get; set; }
            public string CategoryName { get; set; }
        }
    }
    I would also use always the language data types, thus string instead of String. Also don't use two different data types for private field and its property accessor (int <> Int32). When there is no special property access handling the I prefer auto-implemented properties. Also use a base class, which implements the basic operations of your DTO. This includes especially the GetHashCode() method and often the ToString() method.


    • Marked as answer by Lisa Zhu Wednesday, July 25, 2012 9:52 AM
    Thursday, July 19, 2012 7:40 AM
  • thanks Stefan, still I have some questions don't understand.

    For the coding you provided, could you explain why you use "public abstract class BaseDataTransferObject", instead of just typing "public class"?

    For .net 3.0 or later, we can use the short-style like "public int CategoryID { get; set; }", right?  So, I don't need to use the long-style in the future, right?

    Please advice ~~

    Thursday, July 19, 2012 8:21 AM
  • An abstract class is a class which cannot be instantiated, thus a

    BaseDataTransferObject obj = new BaseDataTransferObject ();

    will throw an error. The basic idea for abstract classes is that you have a container to implement the methods and properties which are the same for all derived classes (the DRY principle).

    The idea behind it is quite simple: you normally need a marker for set-based operations on different DTO's. While you could use a marker interface, using a abstract base class in many scenarios is appropriate. So you often get an hierarchy like

    interface IDataTransferObject {}

    abstract cass BaseDataTransferObject: IDataTransferObject {}

    class ConcreteDataTransferObject : BaseDataTransferObject {}

    btw, abstract classes are normally named with Base prefix. Here is a simple example.

    Thursday, July 19, 2012 8:59 AM
  • Thanks, but in my application, I never used abstract class and seems like it's well organized OOP application, so, why should I need to use it?  Sorry, I still can't get the main point.   Please help ~

    Thursday, July 19, 2012 10:09 AM
  • It's about abstraction. Consider that each entity has a unique ID. Then you may use this ID for comparison. Without base class you must implement the necessary methods in every class. This means copy and past, thus violation DRY.
    Thursday, July 19, 2012 12:25 PM
  • I would and often do take a different approach than Stefan recommends using the Visitor Pattern which simply entails events! I prefer event based programming because to me it is the best for "Separation of Concerns"  the main idea being that the sender could care less who the listeners are!  This is a very important concept for "Loose Coupling" as it is the absolute best way to support asynchronous techniques which include Parralel programming.  This means that you can build lighting fast applications centered around an event based model.

    //Step 1 Create a class and name it 'Delegates.cs', remove all the code but just keep the namespace declaration and put in the delegate signatures like this public delegate void OnNewCustomer(ObservableCollection<Customer>); //Step 2 in the class that notifies everyone that there's new data, create a static event... public static event OnNewCustomer GotNewData; //in the logic that gets the data and needs to tell listeners, do this var MyCustomerCollection = new ObservableCollection<Customer>(); MyCustomerCollection = GetCustomerData();

    //Do the notification if(GotNewData!=Null){ GotNewData(MyCustomerCollection);


    And you can get tricky with this as well by doing what Stefan recommended you can pass Actions and or Functions as event parameters as well.  But for now just focus on passing the data over to a registerd listener.


    JP Cowboy Coders Unite!


    • Edited by Mr. Javaman II Thursday, July 19, 2012 12:43 PM
    • Marked as answer by Lisa Zhu Wednesday, July 25, 2012 9:55 AM
    Thursday, July 19, 2012 12:41 PM