Предположим, что
public class Product: Entity
{
public IList<Item> Items { get; set; }
}
Предположим, что я хочу найти элемент с max что-то... Я могу добавить метод Product.GetMaxItemSmth()
и сделать это с Linq (from i in Items select i.smth).Max()
) или с помощью ручного цикла или чего-то еще. Теперь проблема заключается в том, что это загрузит полную коллекцию в память.
Правильным решением будет выполнение конкретного запроса БД, но сущности домена не имеют доступа к репозиториям, правильно? Так что либо я делаю
productRepository.GetMaxItemSmth(product)
(что является уродливым, нет?), или даже если сущности имеют доступ к репозиториям, я использую IProductRepository
из объекта
product.GetMaxItemSmth() { return Service.GetRepository<IProductRepository>().GetMaxItemSmth(); }
который также является уродливым и является дублированием кода. Я даже могу пошутить и сделать расширение
public static IList<Item> GetMaxItemSmth(this Product product)
{
return Service.GetRepository<IProductRepository>().GetMaxItemSmth();
}
что лучше только потому, что на самом деле он не мешает сущности с репозиторием... но все равно дублирует метод.
Теперь проблема заключается в том, следует ли снова использовать Product.GetMaxItemSmth()
или productRepository.GetMaxItemSmth(product)
.... Я что-то пропустил в DDD? Что здесь правильно? Просто используйте productRepository.GetMaxItemSmth(product)
? Это то, что все используют и довольны?
Я просто не чувствую, что это правильно... если я не могу получить доступ к продукту Items
из самого продукта, зачем мне эта коллекция в Product
вообще? И тогда, может ли Product
делать что-нибудь полезное, если он не может использовать конкретные запросы и получать доступ к своим коллекциям без хитов производительности?
Конечно, я могу использовать менее эффективный способ и неважно, и когда он замедляется, я буду вводить вызовы репозитория в сущности в качестве оптимизации... но даже это звучит не так, не так ли?
Одна вещь, о которой стоит упомянуть, может быть, это не совсем DDD... но мне нужно IList в продукте, чтобы получить мою схему БД, сгенерированную с помощью Fluent NHibernate. Не стесняйтесь отвечать в чистом контексте DDD.
UPDATE: здесь описывается очень интересная опция: http://devlicio.us/blogs/billy_mccafferty/archive/2007/12/03/custom-collections-with-nhibernate-part-i-the-basics.aspx, а не только для обработки запросов на сборку, связанных с DB, но также может помощь с контролем доступа к коллекции.