Промежуточные недостатки поставщика услуг - PullRequest
0 голосов
/ 28 апреля 2020

Я пытаюсь получить доступ к экземпляру пользовательского класса во время метода ConfigureServices.

У меня есть read , что я могу создать промежуточного поставщика услуг для этого:

public void ConfigureServices(IServiceCollection services)
{
    // .... Other Stuff ....
    services.AddSingleton<Wso2Actions>();
    var serviceProvider = services.BuildServiceProvider();
    var wso2Actions = serviceProvider.GetService<Wso2Actions>();
    // .... Other stuff ....

У меня есть 3 вопроса относительно этой техники:

  1. Каковы недостатки создания этого «Поставщика промежуточных услуг»?
  2. Будет ли мой wso2Actions объект все еще будет управляться структурой внедрения зависимостей? (Как будто это было введено позже?)
  3. Будет ли мне лучше просто "обновить" объект сам?
    • var wso2Actions = new Wso2Actions(); services.AddSingleton<Wso2Actions>(wso2Actions);
    • Кажется, я помню, что читал, что передача экземпляра в механизм DI приводит к ухудшению управления временем жизни.

1 Ответ

1 голос
/ 28 апреля 2020

Каковы недостатки создания этого «промежуточного поставщика услуг»?

В вашем приложении может оказаться несколько контейнеров. Один из главных недостатков - ваши одноэлементные сервисы могут существовать в нескольких контейнерах. т. е. несколько экземпляров одиночной службы.

Начиная с ASP. NET Core 3.0, если вы вызываете BuildServiceProvider в методах настройки, вы увидите предупреждение:

Calling 'BuildServiceProvider' from application code results in an additional copy of
singleton services being created. Consider alternatives such as dependency injecting 
services as parameters to 'Configure'.

Комментарий от @ devNull дает больше подробностей, если вы также хотите прочитать.

Будет ли мой объект wso2Actions по-прежнему управляться инфраструктурой внедрения зависимостей?

Да.

(Как будто его впрыснули позже?)

Нет. Если позже вы добавите wso2Actions, например, в свой контроллер, контейнер, используемый для разрешения экземпляра, будет контейнером, используемым ASP. NET Core. Принимая во внимание, что в вашем ConfigureServices экземпляр разрешается с использованием временного контейнера, созданного вашим кодом.

Обратите внимание, что оба контейнера независимы и могут содержать разные регистрации служб.

Буду ли я Вам лучше просто «обновить» объект?

Если вы хотите использовать new, то почему бы и нет.

Если вы готовы использовать внедрение зависимостей, Есть несколько вариантов в зависимости от того, для чего wso2Actions предназначен:

Переместите свой код в Configure

Очевидно, вы можете переместить свой код в Configure, что Вызывается после сборки контейнера:

var wso2Actions = app.ApplicationServices.GetService<Wso2Actions>();

Использовать шаблон параметров

Чтение this .

services.AddOptions<MyOptions>("optionalName")
    .Configure<Service1, Service2, Service3, Service4, Service5>(
        (o, s, s2, s3, s4, s5) => 
            o.Property = DoSomethingWith(s, s2, s3, s4, s5));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...