Инициализировать синглтон после настройки внедрения зависимостей, но до первого http-запроса - PullRequest
0 голосов
/ 03 июня 2019

Я использую функции Azure версии 2.x. Он имеет встроенную поддержку для внедрения зависимостей .

Таким образом, я могу зарегистрировать свой сервис IMyService для DI в одноэлементной области, используя:

public class Startup : FunctionsStartup
{
    public override void Configure(IFunctionsHostBuilder builder)
    {
        builder.Services.AddSingleton<IOther, DefaultOther>();
        builder.Services.AddSingleton<IMyService, DefaultMyService>();  // IMyService depends on IOther.
    }
}

Экземпляр DefaultMyService создается при первом запуске функции. Это означает, что первый запрос медленнее, потому что он выполняет тяжелую инициализацию, которая происходит внутри DefaultMyService (он заполняет кэш и т. Д.).

Вопрос: есть ли способ создать DefaultMyService раньше, чем первый запрос?

A аналогичный вопрос был задан для ядра asp.net, и ответы там предлагают несколько решений, но ни одно из них не работает в контексте приложения-функции:

Вариант 1: создать экземпляр моей службы (здесь происходит инициализация), а затем зарегистрировать экземпляр (вместо регистрации типа)

var foo = new Foo();
services.AddSingleton<IFoo>(foo);

Это не работает, потому что в моем случае IMyService зависит от других служб, которые не создаются в тот момент, когда я регистрирую IMyService в методе Configure. Сбой с ошибкой, которая описана здесь .

Вариант 2: Другое предложение заключается в использовании перегруженного метода настройки:

public void Configure(IApplicationBuilder app, IFoo foo) 
{
    ...
}

Это также не работает, потому что в случае приложения-функции единственный выполняемый метод configure - это Configure(IFunctionsHostBuilder builder), а другие перегрузки не вызываются.

1 Ответ

2 голосов
/ 03 июня 2019

, потому что он выполняет тяжелую инициализацию, которая происходит внутри DefaultMyService

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

Ваш вопрос похож на это q / a , и мой совет был бы таким же: извлеките логику инициализации из конструктора и либо выполните следующее:

  • Выполните инициализацию перед подключением графа объекта и предоставьте конфигурации DI инициализированный объект, или
  • Разрешить и вызвать граф объектов непосредственно после фазы регистрации и перед первым запросом таким образом, чтобы данные могли быть инициализированы.
...