locked
Where to place domain functionality in a 3-tiered application RRS feed

  • Question

  • User1885169913 posted

    I have the following situation:

    - frontend (mvc)

    - backend

    - database

    Between the frontend and the backend I have a WCF service and besides the 2 I have created a class library which I reference in both ui and backend service layer with the interfaces needed for the .svc but also the domain/data types.

    Now the question: say if I have some domain, in the commonly referenced domain class like this (took this from automapper.codeplex.com as example):

    public class Order
    {
    	private readonly IList<OrderLineItem> _orderLineItems = new List<OrderLineItem>();
    	public Customer Customer { get; set; }
    	public OrderLineItem[] GetOrderLineItems()
    	{
    		return _orderLineItems.ToArray();
    	}
    	public void AddOrderLineItem(Product product, int quantity)
    	{
    		_orderLineItems.Add(new OrderLineItem(product, quantity));
    	}
    	public decimal GetTotal()
    	{
    		return _orderLineItems.Sum(li => li.GetTotal());
    	}
    }
    public class Product
    {
    	public decimal Price { get; set; }
    	public string Name { get; set; }
    }
    public class OrderLineItem
    {
    	public OrderLineItem(Product product, int quantity)
    	{
    		Product = product;
    		Quantity = quantity;
    	}
    	public Product Product { get; private set; }
    	public int Quantity { get; private set;}
    	public decimal GetTotal()
    	{
    		return Quantity*Product.Price;
    	}
    }
    public class Customer
    {
    	public string Name { get; set; }
    }


    Then where do I need to call the method GetTotal on Order class? In the backend and put it in some transfer class and then fill the domain class up again in the frontend or? How do people do this kind of trick? As I think the domain methods may be passed over the WCF service? Or not? Please guide me.



    Tuesday, June 15, 2010 3:40 PM

Answers

  • User-2074625069 posted

    In my experience your UI is all about presenting a view of your domain to users, whether thats orders that have yet to be dispatched or customers that owe you money. My domain model sits behind a service layer/facade and when I need to get something like an order for a customer to view I don't want to return my fat domain object so instead I return a View of the order specific as a simple DTO - just getters and settters. I don't map it back to a domain model as my presentation layer is dumb and simply displays what it gets back. If the presentaation layer has some logic I may convert my view into a presentation model which will only contain logic specific to the view - no domain logic.

    I have never heard of it before. Is there a good overview of all these kinds of patterns? I am only familiar with those of the gang of 4.

    toas1 posted a link to the CQRS pattern, otherwise checkout the whole Domain Driven Design movement that may be of interest.

    Shameless Plug Embarassed: I have just written a book on ASP.NET Design Patterns that I have used and found succesful that will be coming out at the end of July that might help you. I have a case study as featured in the book based on some of these patterns here: http://aspnetdesignpatterns.codeplex.com/.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, June 17, 2010 11:39 AM

All replies

  • User-2004844803 posted

    well,

    First, since you have all the data you need for the calculations in the getTotal methods and you (I suppose) want to avoid any unnecessary WCF calls keep them in your entities. Second, that kinda call for a method that calculates the total like that does not really fall within the frame off what to expose as a service anyway. Its better suited on the entity.


    Tuesday, June 15, 2010 4:02 PM
  • User1885169913 posted

    So my initial thought is correct? Are there any other points of view about this or some good advice on how to deal with this? Can such methods be sent over the service boundary? Or are there better architectures? I thought to do it on the model/entitty itself since I could be needing the method on both sides.


    Tuesday, June 15, 2010 4:09 PM
  • User-2004844803 posted

    yes, it is.

    Off what I can see you are leaning towards a domain driven design so my suggestion for you is to find some good reading about DDD, there are a lot a great books in that subject and one off the best to start with is Eric Evans - Domain Driven Design.

    And the answer to your last question, yes the method could be called using a service but it shouldnt. The reson is stated in the definition off a Service: "A Domain Service provides functionality that does not sit comfortably on a single Entity or Value Object".

    Hope this helps


    Wednesday, June 16, 2010 3:27 AM
  • User-2074625069 posted

    Then where do I need to call the method GetTotal on Order class? In the backend and put it in some transfer class and then fill the domain class up again in the frontend or? How do people do this kind of trick? As I think the domain methods may be passed over the WCF service? Or not? Please guide me.
     

    If you are using a WCF service layer it may make sense to pass back Data Transfer objects or ViewModels instead of full Domain objects as you will loose any methods when serializing. When you convert your domain objects into ViewModels (you can use AutoMapper for this) to be passed to your frontend this will call the GetTotal method and add it as a property to the OrderSummaryViewModel as shown below.

        public class OrderSummaryViewModel
        {
            public decimal Total { get; set; }
            public string CustomerName { get; set; }
    
            //...
        }


    I have used this method for a case study in my ASP.NET Design Patterns book which should hit the shelves soon, you can grab the source code for the case study at http://www.codeplex.com/aspnetdesignpatterns. Let me know if you have any questions.

    Wednesday, June 16, 2010 3:38 AM
  • User1885169913 posted

    When you convert your domain objects into ViewModels (you can use AutoMapper for this) to be passed to your frontend this will call the GetTotal method and add it as a property to the OrderSummaryViewModel as shown below
     

    I thought viewmodels were only to be used in the UI layer (ASP.NET MVC). Wouldn't using viewmodels in the service layer lead to flattened out objects? What if I would have to include a feature rich UI layer like WPF afterwards? Wouldn't I be losing valuable information?

    Wednesday, June 16, 2010 8:38 AM
  • User-2004844803 posted

    Hey Nyla,

    Take a look at the CQRS pattern. That way you can use simple DTO's when querying data to display in the UI and domain specific entites on the command side. I think that might be something for you.

    Wednesday, June 16, 2010 8:54 AM
  • User-2074625069 posted

    I thought viewmodels were only to be used in the UI layer (ASP.NET MVC). Wouldn't using viewmodels in the service layer lead to flattened out objects? What if I would have to include a feature rich UI layer like WPF afterwards? Wouldn't I be losing valuable information?

    I return flatterned DTO/Views of the Domain Model from my service layer (after all if there are going to be serialised they won't be able to have any behaviour anyway, updates go through a service call rather like the pattern toas1 mentioned CQRS.

    Wednesday, June 16, 2010 2:06 PM
  • User1885169913 posted

    after all if there are going to be serialised they won't be able to have any behaviour anyway
     

    And after you got those flattened out objects you map them again back to the original domain model? Or you continue using those flattened out objects in your UI layer?

    CQRS

    I have never heard of it before. Is there a good overview of all these kinds of patterns? I am only familiar with those of the gang of 4.

    Thursday, June 17, 2010 7:28 AM
  • User-2074625069 posted

    In my experience your UI is all about presenting a view of your domain to users, whether thats orders that have yet to be dispatched or customers that owe you money. My domain model sits behind a service layer/facade and when I need to get something like an order for a customer to view I don't want to return my fat domain object so instead I return a View of the order specific as a simple DTO - just getters and settters. I don't map it back to a domain model as my presentation layer is dumb and simply displays what it gets back. If the presentaation layer has some logic I may convert my view into a presentation model which will only contain logic specific to the view - no domain logic.

    I have never heard of it before. Is there a good overview of all these kinds of patterns? I am only familiar with those of the gang of 4.

    toas1 posted a link to the CQRS pattern, otherwise checkout the whole Domain Driven Design movement that may be of interest.

    Shameless Plug Embarassed: I have just written a book on ASP.NET Design Patterns that I have used and found succesful that will be coming out at the end of July that might help you. I have a case study as featured in the book based on some of these patterns here: http://aspnetdesignpatterns.codeplex.com/.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, June 17, 2010 11:39 AM