Czy można rozwiązać wystąpienie IOptions<AppSettings>
z ConfigureServices
metody w programie Startup? Zwykle możesz użyć IServiceProvider
do zainicjowania instancji, ale nie masz go na tym etapie, gdy rejestrujesz usługi.
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
Muhammad Rehan Saeed
źródło
źródło
ConfigureServices
metody.BuildServiceProvider
powoduje ostrzeżenie, jeśli jest używane w kodzie aplikacji, na przykładConfigureServices
powoduje powstanie dodatkowej kopii pojedynczych usług. Utworzony. Odpowiedź Ehsana Mirsaeedi jest tutaj najbardziej idealnym rozwiązaniem w takich przypadkach.Najlepszym sposobem tworzenia wystąpień klas zależnych od innych usług jest użycie przeciążenia Add XXX, które udostępnia IServiceProvider . W ten sposób nie musisz tworzyć instancji pośredniego dostawcy usług.
Poniższe przykłady pokazują, jak można użyć tego przeciążenia w metodach 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; });
źródło
Najprostszym i najbardziej poprawnym sposobem osiągnięcia tego we wszystkich wersjach ASP.NET Core jest zaimplementowanie
IConfigureOptions<TOptions>
interfejsu. Chociaż było to już od .NET Core 1.0, wydaje się, że niewiele osób wie o tym, jak to wszystko działa .Na przykład chcesz dodać moduł weryfikacji modelu niestandardowego, który jest zależny od jednej z innych usług aplikacji. Początkowo wydaje się to niemożliwe - nie ma sposobu na rozwiązanie,
IMyServiceDependency
ponieważ nie masz dostępu doIServiceProvider
:public class MyModelValidatorProvider : IModelValidatorProvider { public MyModelValidatorProvider(IMyServiceDependency dependency) { ... } } public void ConfigureServices(IServiceCollection services) { services.AddControllers(options => { options.ModelValidatorProviders.Add(new MyModelValidatorProvider(??????)); }); }
Ale „magia”
IConfigureOptions<TOptions>
sprawia, że jest to takie proste: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>(); }
Zasadniczo każda konfiguracja, którą wykonałeś w
Add***(***Options)
delegatach,ConfigureServices
jest teraz przenoszona do metody TwojejIConfigureOptions<TOptions>
klasyConfigure
. Następnie rejestrujesz opcje w ten sam sposób, w jaki rejestrujesz każdą inną usługę i gotowe!Aby uzyskać więcej szczegółów, a także informacje o tym, jak to działa za kulisami, odsyłam do zawsze doskonałego Andrew Lock .
źródło
Szukasz czegoś takiego jak śledzenie? Możesz spojrzeć na moje komentarze w kodzie:
// 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
źródło
Chcesz pomóc innym, którzy wyglądają tak samo, ale także podczas korzystania z Autofac.
Jeśli chcesz uzyskać ILifetimeScope (tj. Kontener o aktualnym zakresie), musisz wywołać
app.ApplicationServices.GetAutofacRoot()
metodę,Configure(IApplicationBuilder app)
która zwróci instancję ILifetimeScope, której możesz użyć do rozwiązania usługpublic void Configure(IApplicationBuilder app) { //app middleware registrations //... // ILifetimeScope autofacRoot = app.ApplicationServices.GetAutofacRoot(); var repository = autofacRoot.Resolve<IRepository>(); }
źródło