web-dev-qa-db-ja.com

ServiceCollectionからIConfigurationを取得する

モジュールのタイプを登録するためにServiceCollectionの独自の拡張メソッドを作成しています。オプションを登録するには、コレクションからIConfigurationインスタンスにアクセスする必要があります。

拡張方法

public static IServiceCollection AddApi(this IServiceCollection services)
{
  // Get configuration from collection
  var configuration = (IConfiguration) services.FirstOrDefault(p => p.ServiceType == typeof(IConfiguration)).ImplementationInstance;

  services.Configure<DatabaseOptions>(configuration.GetSection("Database"));
}

これは、コレクションからIConfigurationインスタンスを取得する正しい方法ですか、それともよりエレガントな解決策がありますか? IConfigurationインスタンスをパラメーターとしてメソッドに追加したくありません。

15
Jehof

コメントによると、拡張メソッドを次のように変更したため、オプションの構成セクションを提供するのはアプリケーションのcomposer)までです。

public static IServiceCollection AddApi(this IServiceCollection services, IConfiguration databaseConfiguration)
{  
  services.Configure<DatabaseOptions>(databaseConfiguration);
}

startUpクラスからの呼び出しは次のようになります。

public void ConfigureServices(IServiceCollection services)
{
  services.AddApi(Configuration.GetSection("Database"));
  services.AddMvc();
}

このように使用するかどうかの決定は、主にこれらのコメントによるものです。この方法は、アプリケーションで使用する内部コンポーネントよりも、多くの開発者が使用するコンポーネントを開発するときに、より適切です。

構成ファイル(ASP.NETコアのスタートアップクラス)以外のどこからでもIConfigurationにアクセスするのは悪い設計です。これは、構成ファイルが変更できない特定の構造を持つ必要があることを意味します。代わりに、.Configure(Configuration.GetSection( "MyLibConfi‌ g")のように、コンポジションルート内の構成クラスを構成し、IConfigurationオブジェクトを渡す拡張メソッドを記述します。このようにして、アプリケーションを作成する開発者コンポーネントからそれをappsettings.json内のどこに配置するかを決定できます

または、2つのライブラリがIConfigurationを直接参照し、構成内に同じセクションがある場合、どのように競合を解決しますか?つまりJsonSettingsですが、完全に異なる構造になっていますか?これを解決するには、それを作成する開発者がセクション名を選択し、.Configureを介してオプションを設定する拡張メソッドに渡します。

3
Jehof

IServiceCollectionIConfigurationをラップする独自の「サービスコレクション」タイプを作成し、すべてのモジュールがそのタイプを使用してサービスを登録しました。例えば:

public interface IMyServiceCollection
{
    public IServiceCollection Services { get; set; }

    public IConfiguration Configuration { get; set; }
}

public static void AddFooModule(this IMyServiceCollection myServices)
{
    var services = myServices.Services;
    var config = myServices.Configuration;
}

次に、次のように、IMyServiceCollectionの実装を作成する構成インスタンスをパラメーターとして使用して、拡張メソッドを作成する必要があります。

public static IMyServiceCollection CreateServiceCollection(this IServiceCollection services, IConfiguration config)
{
    return new MyServiceCollection 
    { 
        Services = services,
        Configuration = config
    };
}

これをモジュラーフレームワークで使用していることに注意してください。単純なアプリケーションの場合、これはやりすぎです。

私もあなたの解決策は素晴らしいと思います。ただし、IConfigurationインスタンスに頻繁にアクセスする必要がある場合は、サービスコレクションで何度も何度も検索するのが面倒です。

3
Henk Mollema