none
Where does this logic belong? RRS feed

  • Question

  • Hi all, I am building a n-tier application using the Domain Model approach.  Please take the following scenario into consideration:

    A user is adding a new Customer through a webform.  Assume that adding a new Customer also means that some default Address (I know this makes no sense) also has to be added.  In my scenario I am not using DTOs between the presentation and the service layer, rather I am using the domain objects directly.

    Service Layer:

    CustomerServices.AddCustomer(Customer c);
     - this class contains the dataContext of entity framework

    Business Layer (Entity Framework):
    Customer domain object
    Address domain object

    My question is as follows:  I know the service layer is supposed to "orchestrate" using the business objects and their business logic, yet I am not sure what that means.  For example does my CustomerService.AddCustomer(Customer c) instanciates the Address class, assigns it to the Customer class, then calls the datacontext.AddToCustomer() or is this something that is considered business logic and has to somehow be part of the Customer class's logic?  For example CustomerService.AddCustomer(Customer c) would create a Customer and call Customer.AddDefaultAddress() where the logic for the address etc would be encopsulated in the Customer class.

    I hope this question makes sense, what I am afraid of is that I am putting business logic in my service layer, where as far as I understand it shouldn't be.
    Tuesday, June 30, 2009 6:19 PM

All replies

  • Your problem doesn't make sense.  It the domain objects implement the address object, then you'd be able to call it directly.  This leads me to the point, that you should not use domain objects in presentation layers, as you have coupled the presentation to the service layer.

    To your question, the answer is, it depends.  It completely depends on what it is supposed to do.  You could have an address as part of the customer, it sort of makes sense logically.  You could have an address business logic class, that you pass the customer, and the two are joined, or the customer class that you pass the address and it joins the data.  Notice that I am saying joins, as a customer can have more than one address, and an address can belong to more than one user.  This creates a many to many relationship, which does complicate the scenario a little.

    The other, more service oriented way to do things is that you have logic for returning addresses, and you pass the customerId, and that returns you a bunch of addresses.  You could also have customer logic, and pass it an addressId, and it returns a bunch of users.

    Yes, designing this would mean separation of concerns, but service orientation also requires that the logic is self contained, or encapsulated.  I think that both of the above scenarios are valid, as it depends where you are viewing the data from.

    The whole point is, without the knowledge of how that application is supposed to work, the answers can only be aducated guesses, but personally, I would do both of the above scenarios (using Ids and not objects to remove the coupling across concerns)

    I hope this helps,

    Martin.

    MCSD, MCTS, MCPD. Please mark my post as helpful if you find the information good!
    Tuesday, June 30, 2009 9:36 PM
  • Martin, thanks for your reply.  I understand what you're saying by not passing the domain objects around, I understand that DTOs would be better.  I am creating a POC at this point so I am taking a "shortcut".  Let me give you an example of a piece of code, perhaps that will clear up my question.

    This is my service layer, when the GUI adds an author I want to configure that authors salary.
        public class AuthorServices : IAuthorServices
        {
            /// <summary>
            /// Adds an author
            /// </summary>
            /// <param name="author"></param>
            /// <returns></returns>
            int IAuthorServices.AddAuthor(Author author)
            {
                //configure salary level
                author.ConfigureSalary();
                
                //add author to the data context
                dataContext.AddToAuthor(author);
    
                //commit unit of work to database
                int rowsAffected = dataContext.SaveChanges(true);
                return rowsAffected;
            }
    
        }
    This is my business layer, it contains my entity framework model and partial classes that add behavior to those domain objects.  Here is the example of the Author partial class.

        public partial class Author
        {
    
            /// <summary>
            /// Configures an author's salary level.
            /// </summary>
            public void ConfigureSalary()
            {
                //random number gen
                Random r = new Random();
    
                //create a new payroll object
                Payroll authorsPay = new Payroll();
    
                //randomly assign a salary
                authorsPay.Salary = r.Next(0, 100000);
    
                //add the payroll object to the author
                this.Payroll.Add(authorsPay);
            }
    
            #endregion
    
        }
    So from this example, is the logic distributed properly between the service layer AddAuthor() and the business logic that is part of the domain object?  In other words that conifugration of the salary is business logic, therefore it is part of the domain object itself as opposed of putting the code of configuring the salary directly in AddAuthor() the service layer class.

    I really appreciate the help.
    Wednesday, July 1, 2009 1:43 PM