Как я могу получить доступ к поисковым данным через внедренный сервис изнутри объекта? - PullRequest
0 голосов
/ 24 мая 2019

Мое приложение использует DDD с .NET Core и EF Core.У меня есть некоторые бизнес-правила, которые работают внутри организации, которой нужно сверять даты с кэшированным списком дат компаний.Праздничные дни компании загружаются из базы данных и кэшируются службой приложений, которая настроена с нашим контейнером DI, чтобы ее можно было вводить в наши контроллеры и т. Д.

Я не могу определить, как это сделать, или это правильно / лучше всего.подход, чтобы сервис внедрялся в сущность, чтобы он мог получить эти даты при выполнении бизнес-правил.Я нашел этот ответ , который, кажется, демонстрирует один из способов сделать это, но я хотел посмотреть, есть ли какие-либо дополнительные опции, потому что этот способ имеет некоторый запах кода на первый взгляд (добавлениесвойство DbContext для захвата контекста, внедренного закрытым конструктором).

Есть ли другие способы достижения чего-либо подобного?

1 Ответ

1 голос
/ 24 мая 2019

ORM классы очень редко являются объектами вашего домена.Если вы можете начать с вашего домена и без проблем отображать ORM без необходимости изменений или атрибутов, специфичных для инфраструктуры, то это нормально;иначе вам нужно отделить ваши доменные объекты от ваших объектов ORM.

Вы не должны внедрять какие-либо сервисы или репозитории в агрегаты.Агрегаты должны сосредоточиться на командной / транзакционной стороне решения и работать с предварительно загруженным состоянием и избегать запроса дополнительного состояния через любые передаваемые механизмы.Состояние должно быть получено и передано агрегату.

В вашем конкретном сценарии я бы предложил загрузить ваш BusinessCalendar, а затем передать его вашему агрегату при выполнении какой-либо функции, например:

public class TheAggregate
{
    public bool AttemptRegistration(BusinessCalendar calendar)
    {
        if (!calendar.IsWorkingDay(DateTime.Now))
        {
            return false;
        }

        // ... registration code

        return true;
    }

    // or perhaps...

    public void Register(DateTime registrationDate, BusinessCalendar calendar)
    {
        if (!calendar.IsWorkingDay(registrationDate))
        {
            throw new InvalidOperationException();
        }

        // ... registration code
    }
}

Другой вариант - заставить ваш домен игнорировать этот бит и возложить бремя на вызывающий код.Таким образом, если вы попросите свой домен сделать что-то, он сделает это, поскольку, возможно, в некоторых обстоятельствах регистрация в нерабочий день (в моем тривиальном примере) может быть выполнена.В этих случаях прикладной уровень отвечает за проверку календаря на «нормальную» регистрацию или переопределение поведения по умолчанию при некоторых обстоятельствах.Это тот же подход, который можно использовать для авторизации.Прикладной уровень отвечает за авторизацию, и домен не должен заботиться об этом.Если вы можете позвонить по коду домена, то вам разрешено это делать.

...