Как заставить создание экземпляра класса в .NET Core DI? - PullRequest
0 голосов
/ 02 октября 2018

У меня есть следующий код:

public void ConfigureServices(IServiceCollection services)
{
   services.AddOptions();

   services.Configure<MyConfig>(Configuration.GetSection("MySection"));
   services.AddSingleton<IMyClass>(sp => new MyClass(sp.GetService<IOptions<MyConfig>>()));
}

Это регистрирует синглтон для MyClass, и теперь я могу заставить мои контроллеры принимать аргумент конструктора типа IMyClass.Это работает как задумано.

MyClass запускается первым, только когда контроллеру требуется IMyClass.Тем не менее, я хотел бы, чтобы MyClass был создан до того, как кто-нибудь когда-либо попросит об этом (так как он выполняет некоторую работу в своем конструкторе, которая занимает немного времени).

Я мог бы сделать что-то вроде:

public void ConfigureServices(IServiceCollection services)
{
   services.AddOptions();

   services.Configure<MyConfig>(configuration.GetSection("MySection"));

   var myinstance = new MyClass(/*...*/);  // How do I get MyConfig in here?
   services.AddSingleton<IMyClass>(myinstance);
}

... но тогда я не могу добраться до конфигурации, поскольку у меня нет ссылки на IServiceProvider (переменная sp в первом примере кода).Как мне добраться до sericeprovider или что мне нужно сделать, чтобы экземпляр был инициализирован как можно скорее?

Ответы [ 2 ]

0 голосов
/ 03 октября 2018

Если ваша основная цель - создать экземпляр класса до того, как он потребуется любому контроллеру, вы можете запросить его в методе Configure в Startup.cs, который оставляет ваши регистрации чистыми, но гарантирует, что он будет инициализирован.

public void Configure(IApplicationBuilder app, IHostingEnvironment env, IMyClass myClass)
{
  myClass.Initialize();
}

В зависимости от того, для чего вам нужно создать экземпляр, вы также можете проверить IApplicationLifetime , если вам нужно подключиться к push-сервису при запуске приложения или что-то в этом роде.

applicationLifetime.ApplicationStarted.Register(() => myConnection.Connect());
applicationLifetime.ApplicationStopping.Register(() => myConnection.Disconnect());
0 голосов
/ 02 октября 2018

В этом случае действительно не было необходимости в IOptions<T>, так как вы могли извлечь конфиг и передать его непосредственно вашему классу, но если вы настаиваете на использовании опций, вы можете использовать OptionsWrapper<TOptions> Class

IOptions оболочка, которая возвращает экземпляр параметров.

и передает его вашему экземпляру

// How do I get MyConfig in here?
MyConfig myConfig = configuration.GetSection("MySection").Get<MyConfig>();    
var wrapper = new OptionsWrapper<MyConfig>(myConfig);
var myinstance = new MyClass(wrapper);  
services.AddSingleton<IMyClass>(myinstance);

, извлекая ваши настройки из конфигурации дляОболочка.

Ссылка Конфигурация в ASP.NET Core: привязка к графу объектов

...