Reputation: 145
I am puzzled on handle nested collection in business object via pure ADO.NET solution without 3rd-party ORM frameworks, such as AutoMapper/NHibernate/EF.
Please considering the following scenario:
//SalesOrder
public class SalesOrder
{
ICollection<IOrderItem> OrderLines { get; set; }
}
If we retrieve a SalesOrder entity from database by its repository object like this,
//Retrieve entity via repository object
ISalesOrderRepository repo = new SalesOrderRepository(DbContext);
ISalesOrder order1 = repo.GetOrderByCustomerPo("TN-2202-01");
We can use SQL statement to query data from database and fill data into the corresponding properties of SalesOrder entity.
But how to initialize the nested collection object of order1.OrderLines?
I think there is a way to build up order1.OrderLines by Proxy Pattern like this:
public ICollection<IOrderItem> OrderItems
{
get
{
if(_orderItems == null)
{
IOrderItemLazyLoadingProxy lzProxy = new OrderItemLazyLoadingProxy(this);
_orderItems = lzProxy.Load();
return _orderItems;
}
}
}
I am confused about the above implementation that the domain object is directly coupled with or depend on a proxy object.
So I want to know whether there is a way can handle nested collection transpaerncy in an aggregate root object?
Thanks.
Upvotes: 4
Views: 487
Reputation: 13256
Your domain objects should have Persistence Ignorance. They should not be concerned with persistence concerns directly but you should still be pragmatic.
A repository is responsible for loading an aggregate in its entirety so your SalesOrderRepository
should load the items also. You could go with something along these lines:
public class SalesOrder
{
private readonly List<SalesOrderItem> _items = new List<SalesOrderItem>();
public IEnumerable<SalesOrderItem> Items
{
get { return new ReadOnlyCollection<SalesOrderItem>(_items); }
}
public void AddItem(string product, decimal price)
{
OnAddItem(new SalesOrderItem(product, price));
}
public void OnAddItem(SalesOrderItem item)
{
_items.Add(item);
}
}
Your repository would fetch the item date and instantiate them. The OnAddItem
is used for historical data and only to populate the internal list whereas the AddItem
is an actual domain command indicating that something new has happened.
Just some ideas :)
Upvotes: 3