Я заранее извиняюсь, если люди считают, что это было избито до смерти. Я только что провел последние несколько часов и искал много превосходных сообщений здесь, но я все еще смущен.DDD, репозиторий и инкапсуляция
Источником моей путаницы является DTO против DDD и репозиториев. Я хочу, чтобы у моих объектов домена POCO были умны, и я хочу получить их из репозиториев. Но мне кажется, что я должен нарушать некоторые правила инкапсуляции, чтобы сделать эту работу, и похоже, что она может превратить DTO в их головы.
Вот простой пример: в нашем каталоге приложение может быть пакетом, который включает в себя ряд других частей. Таким образом, для Part POCO имеет смысл использовать метод GetChildren(), который возвращает IEnumerable < Part>. Это может даже сделать другие вещи со списком на своем пути.
Но как этот список разрешен? Кажется, что хранилище является ответом:
interface IPartRepository : IRepository<Part>
{
// Part LoadByID(int id); comes from IRepository<Part>
IEnumerable<Part> GetChildren(Part part);
}
И
class Part
{
...
public IEnumerable<Part> GetChildren()
{
// Might manipulate this list on the way out!
return partRepository.GetChildren(this);
}
}
Так что теперь потребители моего каталога, в дополнение к (правильно) загрузки деталей из хранилища, может также обойти некоторые части капсулированных логики, напрямую вызывая GetChildren (часть). Разве это не так плохо?
Я читал, что хранилища должны обслуживать POCO, но DTO хороши для передачи данных «между слоями». Вычисляются многие свойства деталей - цены, например, рассчитываются на основе сложных правил ценообразования. Цена даже не будет в DTO, поступающей из репозитория, поэтому, похоже, передача данных о ценах обратно в веб-службу требует, чтобы DTO потреблял часть, а не наоборот.
Это уже слишком длинное. Где моя голова отвинчена?
Интересно. Но меня смущает «переместите GetChildren (часть) в IPartService и удалите его из части», а затем «Класс Part все еще имеет свойство Childparts». Что, если часть нуждается в массаже своих детей по какой-то причине? – n8wrl
Если массирование должно произойти сразу же после извлечения из репозитория, я бы поставил эту логику в 'IPartService.GetChildren()'. Если вам нужно иметь возможность изменять дочерние части в произвольные моменты времени, вы можете создать другой метод службы, например «IPartService.UpdateChildPartPrices (часть)». (Или оба - вы можете вызывать «UpdateChildPartPrices» из «GetChildren».) –
Спасибо, что нашли время, Джефф! – n8wrl