Как разрешить экземпляр внутри ConfigureServices в ядре ASP.NET
Можно ли разрешить экземпляр IOptions<AppSettings>
из метода ConfigureServices
в Startup? Обычно вы можете использовать IServiceProvider
для инициализации экземпляров, но у вас его нет на этом этапе, когда вы регистрируете службы.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<AppSettings>(
configuration.GetConfigurationSection(nameof(AppSettings)));
// How can I resolve IOptions<AppSettings> here?
}
Ответы
Ответ 1
Вы можете создать поставщика услуг с помощью метода BuildServiceProvider()
на IServiceCollection
:
public void ConfigureService(IServiceCollection services)
{
// Configure the services
services.AddTransient<IFooService, FooServiceImpl>();
services.Configure<AppSettings>(configuration.GetSection(nameof(AppSettings)));
// Build an intermediate service provider
var sp = services.BuildServiceProvider();
// Resolve the services from the service provider
var fooService = sp.GetService<IFooService>();
var options = sp.GetService<IOptions<AppSettings>>();
}
Для этого вам нужен пакет Microsoft.Extensions.DependencyInjection
.
В случае, когда вам просто нужно привязать некоторые параметры в ConfigureServices
, вы также можете использовать метод Bind
:
var appSettings = new AppSettings();
configuration.GetSection(nameof(AppSettings)).Bind(appSettings);
Эта функциональность доступна через пакет Microsoft.Extensions.Configuration.Binder
.
Ответ 2
Лучший способ создания экземпляров классов, зависящих от других служб, - это использовать перегрузку Add XXX, которая предоставляет вам IServiceProvider. Таким образом, вам не нужно создавать экземпляр промежуточного поставщика услуг.
В следующих примерах показано, как можно использовать эту перегрузку в методах AddSingleton/AddTransient.
services.AddSingleton(serviceProvider =>
{
var options = serviceProvider.GetService<IOptions<AppSettings>>();
var foo = new Foo(options);
return foo ;
});
services.AddTransient(serviceProvider =>
{
var options = serviceProvider.GetService<IOptions<AppSettings>>();
var bar = new Bar(options);
return bar;
});
Ответ 3
Вы ищете что-то вроде следующего? Вы можете посмотреть мои комментарии в коде:
// this call would new-up `AppSettings` type
services.Configure<AppSettings>(appSettings =>
{
// bind the newed-up type with the data from the configuration section
ConfigurationBinder.Bind(appSettings, Configuration.GetConfigurationSection(nameof(AppSettings)));
// modify these settings if you want to
});
// your updated app settings should be available through DI now