1. ホーム
  2. c#

[解決済み] ConfigureServices内部でIOptionsインスタンスを解決する方法は?

2022-05-29 21:26:25

質問

のインスタンスを解決することは可能ですか? IOptions<AppSettings> から ConfigureServices メソッドを使用することができますか? ドキュメントには、明示的に :

を使用しないでください。 IOptions<TOptions> または IOptionsMonitor<TOptions>Startup.ConfigureServices. サービス登録の順序により、一貫性のないオプション状態が存在する可能性があります。

サービスプロバイダを手動で作成するには serviceCollection.BuildServiceProvider() を使って手動で作成することもできますが、この場合、警告が発生します。

アプリケーションコードから 'BuildServiceProvider' を呼び出すと、シングルトンサービスのコピーが追加で作成される結果となります。Configure'のパラメータとしてサービスを依存性注入するなどの代替手段を検討してください。

どうすればこれを実現できますか?

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<AppSettings>(
        configuration.GetConfigurationSection(nameof(AppSettings)));

    // How can I resolve IOptions<AppSettings> here?
}

どのように解決するのですか?

サービスプロバイダを使用してサービスを手動で解決する必要がある場合、次のように使用できます。 AddSingleton/AddScoped/AddTransient をオーバーロードすることができます。

// Works for AddScoped and AddTransient as well
services.AddSingleton<IBarService>(sp =>
{
    var fooService = sp.GetRequiredService<IFooService>();
    return new BarService(fooService);
}

もし、あなたが 本当に を使い、中間サービスプロバイダを構築することができます。 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 パッケージで利用できます。