Search code examples
c#architecturedomain-driven-designdata-access-layersoftware-design

What's the recommended way to load an object graph from Data Access Layer?


From a relatively old software architecture book:

In other situations, the same conceptual Get-Orders query might generate different data—for example, a collection of Order objects plus order items information. What should you do? Should you expose two slightly different GetOrders methods out of your DAL? And what if, depending on the user interface, the user might ask the system to return orders, order items, and products by country? Will you define yet another look-alike method in the DAL?

The author suggests using Query Object pattern. Other ways I can think of:

1) Optional parameter for each relation/child collection:

IOrder GetOrder(int id, bool withItems = false);  

2) Tuples

Remove IList from IOrder definition and return a tuple

Tuple<IOrder, IList<IOrderItems>> GetOrderWithItems(int id);  

3) Method overloading

IOrder GetOrder(int id);
IOrder GetOrderWithItems(int id);  

4) Separate methods

The DAL shouldn't deal with this. Retrieving an order with its items should be done in two steps:

IOrder myOder = GetOrder(myOrderId);
myOrder.items = GetOrderItems(myOrderId);    

What would be the best way? Another concern I have is null references. When items = null, DAL clients might confuse it for 0 (order has no items). How to deal with this?

-Convention

null = not loaded/set

empty collection = 0 items

-Wrapper

ItemsWrapper is null: items not loaded

ItemsWrapper.items is null or (empty): 0 items

-Generics (this is probably stupid)

interface IOrder<TVoidableItems> where TVoidableItems : IWithoutItems
{
int id;
TVoidableItems items;
}


interface IWithoutItems{}

interface IWithItems: IWithoutItems { IList<IOrderItems> value;}  

If the second question is off-topic, please let me know and I'll move it to a second thread. I believe it's related. Maybe I shouldn't use domain objects for the DAL in the first place and use simple relation-free types?


Solution

  • What the author (Dino Esposito) is missing in his book is the clear separation of concerns that CQRS brings. If I'm not mistaking, this pattern is completely missing from his book. In Esposito's latest MSDN article, he explains CQRS, so I think he just wasn't that experienced at the time of writing that book. Unfortunately, the article still misses some fundamental abstractions that make query objects really powerful. This article on the other hand, goes into more detail on how to model your application more effectively.