I am trying to get my hands dirty learning DDD (by developing a sample eCommerce site with entities like Order
, OrderLines
, Product
, <
From what I could perceive about Aggregate Root concept I thought Order class should be an aggreagrte root for OrderLine.
Yes, OrderLine's should most likely be under an Order root, since OrderLine's likely make no sense outside of a parent Order.
Should I hardcode the new OrderLine() statement in my UI/Service class
Probably not, though this is how it happens often and it is made to work. The problem, as I see it, is that object construction often happens in different contexts, and the validation constraints differ depending on that context.
Should I define a method with parameters like productID,quantity etc in Order class?
As in:
public OrderLine AddOrderLine(Product product, int Quantity ... )
This is one way to do it. Notice I used a Product class instead of a ProductId. Sometimes one is preferable to the other. I find I use both a lot for various reasons - sometimes I have the ID and there's no good reason to pull the aggregate root, sometimes I need the other root to validate the operation.
Another way I do this is to implement a custom collection for the children.
So I have:
order.OrderLines.Add(product, quantity);
This feels a little more natural or OO, and in particular if an entity root has many child collections it avoids clutter.
order.AddOrderLine()
, order.AddXXX()
, order.AddYYY()
, order.AddZZZ()
versus
order.OrderLines.Add()
, order.ZZZs.Add()
, order.YYYs.Add()
Also, what if I want to remove the hardcoded instantiations from the UI or the Order class using a DI. What would be the best approach for this?
This would be a textbook case for the Factory pattern. I inject such a Factory into my custom collections to support instantiation in those Add()
methods.