5

I've been working with DDD for a few months now and I've come across a few things I'm unsure of.

Take the simplistic example of adding a Product to an Order object. From our Controller, we'd have an int passed via the UI which represents a Product in the database. Which of the following two examples is correct (let me know if they're both wrong)?

Example One:

public class OrderController
{ 
    // Injected Repositories
    private readonly IProductRepository _productRepository; 

    // Called by UI
    public void AddProduct(int productId)
    {
        Order order = ...; // Persisted Order
        Product product = _productRepository.GetProduct(productId);
        order.AddProduct(product);
    }
}

The Controller instantiates the Product itself and adds it in via the method:

void AddProduct(Product product)
{
    productList.Add(product);
}

Example Two:

public class OrderController
{ 
    // Injected Repositories
    private readonly IProductRepository _productRepository; 

    // Called by UI
    public void AddProduct(int productId)
    {
        Order order = ...; // Persisted Order
        order.AddProduct(productId, _productRepository);
    }
}

The Order domain model has the injected product repository passed to it and it gets the Product and adds it:

Product AddProduct(int productId, IProductRepository productRepository)
{
    Product product = productRepository.GetProduct(productId);
    productList.Add(product);

    return product;
}

I've currently gone for the first example, because your Domain Model should never call a service method internally, however I've seen a few examples lately that use my second example and it does look tidy. It seems to me that Example One is verging on Anaemic. Example Two would move all the Product addition logic into the Domain Model itself.

djdd87
  • 67,346
  • 27
  • 156
  • 195
  • It seems the first example would lead a design towards greedy loading of data, and the second towards lazy loading. Which of these do you prefer? – Jace Rhea Nov 10 '10 at 16:20
  • How is your order saved after the product as been added to the in-memory list? Is there some magic happening (sorry I don't know C# maybe the Order object is a proxy managed by a framework?) – Sebastien Lorber Jan 07 '15 at 23:06

2 Answers2

2

Second one is horrible...

Adding a product to order should not have the repository on its signature since repository is not part of the domain.

I tend to go with the first one.

Aliostad
  • 80,612
  • 21
  • 160
  • 208
  • Actually Repository **Interfaces** are part of the domain. The concrete implementation is part of the Domain Infrastructure: http://dddsample.sourceforge.net/architecture.html – djdd87 Nov 10 '10 at 16:13
  • When you go to supermarket and pick up an item and add to your trolley do you specify a repository? Yes repository can be thought as part of infrastructure domain but not business domain. – Aliostad Nov 10 '10 at 16:15
  • No, I'm too busy implementing `IWheel`. But I like your example :). I did think it looked weird; it makes everything tidier but it doesn't seem to meet the rules as I understood them. – djdd87 Nov 10 '10 at 16:17
  • I am not in any way a DDD expert but I understand that the domain objects need to represent/model real objects and processes. In such a way, I would not be happy with having repository in each and every method. – Aliostad Nov 10 '10 at 16:23
  • +1 Yep, I completely agree. I'm glad we've been using Option 1 then. – djdd87 Nov 10 '10 at 16:26
1

Yeah buddy the First one is better...

As if we think in form of objects...

Adding the product to the list has nothing to do with the product repository, it should take only the product.

djdd87
  • 67,346
  • 27
  • 156
  • 195
Genius
  • 1,084
  • 2
  • 10
  • 20