Можно ли разрешить экземпляр IOptions<AppSettings>
из ConfigureServices
метода в запуске? Обычно вы можете использовать его IServiceProvider
для инициализации экземпляров, но на данном этапе, когда вы регистрируете службы, у вас его нет.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<AppSettings>(
configuration.GetConfigurationSection(nameof(AppSettings)));
// How can I resolve IOptions<AppSettings> here?
}
c#
asp.net-core
inversion-of-control
asp.net-core-mvc
Мухаммад Рехан Саид
источник
источник
ConfigureServices
метода.BuildServiceProvider
вызывает предупреждение, если оно используется в коде приложения, например, такConfigureServices
как это приводит к созданию дополнительной копии одноэлементных служб. создан. Ответ Эхсана Мирсаиди здесь - самое идеальное решение для подобных случаев.Лучший способ создания экземпляров классов, которые зависят от других служб, - использовать перегрузку 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; });
источник
Самый простой и правильный способ добиться этого во всех версиях ASP.NET Core - реализовать
IConfigureOptions<TOptions>
интерфейс. Хотя это существует с .NET Core 1.0, кажется, что мало кто знает, как это делает вещи Just Work ™ .В качестве примера вы хотите добавить настраиваемый валидатор модели, который зависит от одной из других служб вашего приложения. Первоначально это кажется невозможным - нет способа решить,
IMyServiceDependency
потому что у вас нет доступа кIServiceProvider
:public class MyModelValidatorProvider : IModelValidatorProvider { public MyModelValidatorProvider(IMyServiceDependency dependency) { ... } } public void ConfigureServices(IServiceCollection services) { services.AddControllers(options => { options.ModelValidatorProviders.Add(new MyModelValidatorProvider(??????)); }); }
Но «волшебство»
IConfigureOptions<TOptions>
делает это так просто:public class ConfigureMvcOptions : IConfigureOptions<MvcOptions> { private IMyServiceDependency _dependency; public MyMvcOptions(IMyServiceDependency dependency) => _dependency = dependency; public void Configure(MvcOptions options) => options.ModelValidatorProviders.Add(new MyModelValidatorProvider(_dependency)); } public void ConfigureServices(IServiceCollection services) { services.AddControllers(); ... // or scoped, or transient, as necessary for your service services.AddSingleton<IConfigureOptions<MvcOptions>, ConfigureMvcOptions>(); }
По сути, любая настройка, которую вы сделали бы в
Add***(***Options)
делегатах,ConfigureServices
теперь перемещается в метод вашегоIConfigureOptions<TOptions>
классаConfigure
. Затем вы регистрируете параметры так же, как и любую другую службу, и готово!Для получения более подробной информации, а также информации о том, как это работает за кулисами, я отсылаю вас к всегда превосходному Эндрю Локку .
источник
Вы ищете что-то вроде подписчиков? Вы можете посмотреть мои комментарии в коде:
// 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
источник
Хотите помочь другим, которые выглядят так же, но и при использовании Autofac.
Если вы хотите получить ILifetimeScope (т.е. контейнер текущей области видимости), вам нужно вызвать
app.ApplicationServices.GetAutofacRoot()
метод,Configure(IApplicationBuilder app)
который вернет экземпляр ILifetimeScope, который вы можете использовать для разрешения служб.public void Configure(IApplicationBuilder app) { //app middleware registrations //... // ILifetimeScope autofacRoot = app.ApplicationServices.GetAutofacRoot(); var repository = autofacRoot.Resolve<IRepository>(); }
источник