Я бы порекомендовал создать «вспомогательную службу» (также известную как фасад службы), которая инкапсулирует доступ к репо и «внедряет» его в метод объекта. В приведенном выше примере можно создать такой сервис, как DiscountProvider
, с методами GetZoneDiscount
, GetGlobalDiscount
, GetLocalDiscount
и GetPricelistDiscount
. Эти методы могут внутренне выполнять доступ к репо в момент их вызова (или заранее, или кэшировать результат, это становится деталью реализации). Сервис можно передать в метод CommercialDocumentEntry.CalculateDiscount
в качестве параметра. Таким образом, бизнес-логика находится в вашей сущности, но ваша сущность на самом деле не знает, обращается ли она к базе данных для получения необходимых данных.
Также обратите внимание, что только потому, что вы позволяете некоторым методам оставаться внутри вашего сервисного уровня (и вне ваших сущностей), вы автоматически не получаете анемичную модель предметной области. Если у вас есть только несколько методов с проблемой, о которой вы упомянули, я, вероятно, избавил бы весь фасад службы от накладных расходов и позволил бы методу оставаться непосредственно в какой-либо службе, как показано в вашем посте. С другой стороны, может быть, ваше собственное предложение по рефакторингу, которое включает в себя выполнение пяти запросов вместо двух, достаточно быстро? Вы измерили это? Проблемы с производительностью следует решать только тогда, когда они оказывают заметное влияние на вашу программу.
Позвольте мне напоследок сказать: оставайтесь прагматичными, пишите код, который необходимо написать, и воспринимайте DDD как руководство, а не как закон.