The main problem is the ability Repositoryto get only aggregate roots (representing aggregates), so you cannot use Repositoryto get positions. This can lead to cumulative encapsulation failure.
I suggest something like:
public interface IOrderItemList {
IEnumerable<OrderItem> GetItems();
}
public class Order {
private IOrderItemList _orderItems;
public IEnumerable<OrderItem> OrderItems
{ get { return _orderItems.GetItems() } };
public Order(IOrderItemList orderItems)
{
_orderItems = orderItems;
}
}
public class OrderItemList : IOrderItemList
{
private IList<OrderItem> _orderItems;
public IEnumerable<OrderItem> GetItems() {
return _orderItems;
}
}
public class OrderItemListProxy : IOrderItemList
{
private OrderItemList _orderItemList;
private int _orderId;
private DbContext _context;
public OrderItemListProxy(int orderId, DbContext context)
{
_orderId = orderId;
_context = context;
}
public IEnumerable<OrderItem> GetItems() {
if (_orderItemList == null)
{
var orderItemEntities = DbContext.Orders
.Single(order => order.Id == _orderId).OrderItems;
var orderItems = orderItemEntites.Select(...);
_orderItemList = new OrderItemList(orderItems);
}
return _orderItemList.GetItems();
}
}
public class OrderRepository
{
private DbContext _context;
Order GetOrder(int id)
{
var orderEntity = _context.Single(order => order.Id == id);
var order = new Order(new OrderItemListProxy(id, _context))
...
...
}
...
}
The most important thing here is that it IOrderItemListcorresponds to the domain layer, but OrderItemListProxycorresponds to the data level.
Finally,
- Instead of
IOrderItemListor another appropriate interface you can use IList<OrderItem>. - - .
- db, , .