Flexberry / NewPlatform.Flexberry.ORM

Flexberry ORM source code
https://www.nuget.org/packages/NewPlatform.Flexberry.ORM/
MIT License
5 stars 11 forks source link

Применение к ORM принципов Dependency Injection #239

Open Anisimova2020 opened 1 year ago

Anisimova2020 commented 1 year ago

Данное issue формируется на основании rfc https://github.com/Flexberry/rfcs/pull/23.

Цель

Изменить ORM для корректного применения принципов DI.

Функциональные требования

  1. Настройка инъекций должна производиться в одном месте.
  2. Из кода ORM и ODataService требуется убрать некорректное применение паттерна DI.

Требования к реализации

Взять ПР в ОРМ https://github.com/Flexberry/NewPlatform.Flexberry.ORM/pull/181 по Dependency Injection и попробовать: 0) обновить ветку до свежей develop-версии. 1) убрать версии ПР определение текущего пользователя (это единственное место, которое прямо явно завязано на Unity и, судя по комментариям проверяющих, это место действительно можно выпилить). 2) выпустить с ветки ПР alpha-версию 7.2 (последняя - это 7.1 в beta, там ещё будут минимальные изменения и выпуск 7.1). 3) подключить эту альфа-версию к ODataService. 4) изменить ODataService при необходимости (там есть прямые инъекции в коде местами + есть ПР https://github.com/Flexberry/NewPlatform.Flexberry.ORM.ODataService/pull/51). 5) сконфигурировать тесты ODataService (там есть startup) в 3 вариантах:

Потом 6) Целенаправленно по аналогии с ОРМ изменить прямые инъекции в ODataService (принять ПР https://github.com/Flexberry/NewPlatform.Flexberry.ORM.ODataService/pull/51, если не сделано ранее). 7) Проверить и доделать пожелания по DI из RFC https://github.com/Flexberry/rfcs/pull/23.

Вероятно, новая версия ORM будет 8.0.0, поскольку совместимость критично нарушится.

Документация

Документацию потребуется изменить, оставив только "правильные" варианты использования инъекций.

NicholasNoise commented 1 year ago

Пункт 5

  • только с встроенным DI (IServiceProvider),

На грани невероятного для сложных приложений из-за отсутствия поддержки именованных регистраций и, как следствие, возможности построения сложного графа зависимостей.

На мой взгляд, целевым состоянием ORM должно быть container-agnostic реализация, а unity можно продолжить использовать, в конце концов оно не содержит уязвимостей и проверено временем.

Anisimova2020 commented 1 year ago

"а unity можно продолжить использовать, в конце концов оно не содержит уязвимостей и проверено временем."

Про Unity уже шло обсуждение https://github.com/orgs/Flexberry/discussions/16 в том году.

Anisimova2020 commented 1 year ago

Выявлено, что в зависимостях ODataService есть проект UserSettingsService В данном проекте есть некорректное (в соответствии с правилами DI) включение зависимости : ныне CurrentUserService не существует и определение аналога интерфейса "CurrentUserService.IUser" по правилам должно быть через конструктор FlexberryUserSettingBS. Соответственно, требуется добавить получение бизнес-серверов в BusinessServerProvider через контейнер (например, IServiceProvider). Поскольку BusinessServerProvider является по сути фабрикой, то DI позволяет туда прокидывать контейнеры.

Отсюда появилось два побочных эффекта:

  1. В конструктор сервиса данных требуется передавать уже 3 параметра (3 - это корректно сформированный BusinessServerProvider с контейнером (например, IServiceProvider)).
  2. Регистрация, например, в Unity такой конструкции выглядит следующим образом:

container.RegisterFactory<IBusinessServerProvider>(new Func<IUnityContainer, object>(o => new BusinessServerProvider(new UnityServiceProvider(o))), FactoryLifetime.Singleton);

Однако регистрация фабрик не поддерживается файлом конфигураций. Соответственно, настройку юнити в части сервисов данных потребуется вынести в код.

Если побочные эффекты совсем нежелательны, то можно в FlexberryUserSettingBS вставить костыль и при Startup задавать в public static поле FlexberryUserSettingBS разрешение зависимости.

bratchikov commented 1 year ago

Самое главное при переработке учесть, что бизнес-сервера не должны отваливаться если программист что-то забудет. Давайте придумаем такую систему, которая будет подстраховывать программистов, когда есть BS-ы в иерархии наследования объектов данных, которые находятся в разных сборках (в разных NuGet-пакетах). Грубо говоря, если я поставляю некоторый NuGet-пакет Security.Objects в котором есть сборка с объектами и бизнес-серверами, то кто бы ни применил этот пакет - он всегда получит работающие бизнес-сервера, даже если не знает о их существовании. Надо чтобы это так и было при переходе на новый принцип DI.