Startup IOptions<AppSettings>
의 ConfigureServices
메서드에서 의 인스턴스를 해결할 수 있습니까? 일반적으로 IServiceProvider
인스턴스를 초기화 하는 데 사용할 수 있지만 서비스를 등록 할 때이 단계에서 사용할 수 없습니다.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<AppSettings>(
configuration.GetConfigurationSection(nameof(AppSettings)));
// How can I resolve IOptions<AppSettings> here?
}
답변
에 대한 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
패키지를 통해 사용할 수 있습니다 .
답변
다른 서비스에 종속 된 클래스를 인스턴스화하는 가장 좋은 방법 은 IServiceProvider 를 제공 하는 Add XXX 오버로드를 사용하는 것입니다 . 이렇게하면 중간 서비스 공급자를 인스턴스화 할 필요가 없습니다.
다음 샘플은 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 MyMvcOptions : 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)
{
// or scoped, or transient
services.AddSingleton<IConfigureOptions<MvcOptions>, MyMvcOptions>();
services.AddControllers();
}
기본적으로 Add***(***Options)
델리게이트에서 수행 한 모든 설정 ConfigureServices
은 이제 IConfigureOptions<TOptions>
클래스의Configure
메서드 . 그런 다음 다른 서비스를 등록 할 때와 같은 방법으로 옵션을 등록하면됩니다.
자세한 내용과 이것이 뒤에서 어떻게 작동하는지에 대한 정보 는 항상 탁월한 Andrew Locke을 소개 합니다.
답변
다음과 같은 것을 찾고 있습니까? 코드에서 내 의견을 볼 수 있습니다.
// 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 (즉, 현재 범위의 컨테이너)를 얻으려면 서비스를 해결하는 데 사용할 수있는 ILifetimeScope 인스턴스를 반환 할 app.ApplicationServices.GetAutofacRoot()
메서드 를 호출해야 Configure(IApplicationBuilder app)
합니다.
public void Configure(IApplicationBuilder app)
{
//app middleware registrations
//...
//
ILifetimeScope autofacRoot = app.ApplicationServices.GetAutofacRoot();
var repository = autofacRoot.Resolve<IRepository>();
}