Zabieram się na naukę DDD i zastanawiam się czy powinienem robić dwa osobne modele dla EF i dla encji domenowych. Z początku wydało mi się to zbyteczne i zrobiłem wspólny model, jednak mam kilka pytań. Oto moja klasa Order:
public class Order: EntityBase
{
private ICollection<OrderLine> _lines{ get; set; }
public Order(Guid id, string name)
{
Id = id;
Name = name;
}
// Empty constructor for EF
protected Order() { }
public string Name { get; private set; }
public IEnumerable<OrderLine> Lines { get => _lines; }
public static class Mappings
{
public const string OrderLinesCollectionName = nameof(_lines);
public static Expression<Func<Order, ICollection<OrderLine>>> Orders{ get => x => x._lines; }
}
}
oraz model OrderLine:
public class OrderLine: EntityBase
{
protected OrderLine(Guid id, string name)
{
Id = id;
Name = name;
}
// Empty constructor for EF
protected OrderLine() { }
public string Name { get; private set; }
public Guid OrderId { get; set; } // co z tym - gdzie to poprawnie ustawiać?
}
Encję Order
traktuje jako aggregate root
, więc chciałbym tam umieścić poniższe funkcję:
-
AddOrderLine(OrderLine line)
-
RemoveOrderLine(OrderLine line)
Mam też implementację IUnitOfWork
oraz IRepository
dla Order
. Chcę, żeby przykładowa logika aplikacji wyglądała:
public void AddOrderLineToOrder(Guid orderId, string orderLineName)
{
Order order = orderRepo.Get(orderId);
OrderLine line = OrderLine.Create(orderLineName);
order.AddOrderLine(line);
orderRepo.Update(order);
unitOfWork.Commit();
}
I teraz moje pytania:
- gdzie spada odpowiedzialność ustawienia
OrderId
w encjiOrderLine
? Zgodnie z DDD pole to powinno być prywatne. Czy w takim razie powinienem dodać funkcęOrderLine.SetOrder(Order order)
? Z punku biznesowego to raczej linie są dodawane do Orderu a nie na odwrót. - czy to prawd, że powinienem mieć repozytoria tylko dla
aggregate root
? Skoro tak, czyIOrderRepository.Update(Order)
też powinno aktualizowaćOrderLine
? - czy mój powyższy kod nie łamie jakiś zasad DDD (wiem, że nie ma go za wiele, ale warto wiedzieć już na początku)?
Pozwolę sobie zawołać @somekind :)