ASP.NET Core2での同じタイプの複数のインスタンスの依存性注入

ブライアン

ASP.NETコア2のWeb APIでは、私は、注入する依存性注入を使用したいhttpClientAのインスタンスHttpClientControllerA、インスタンスhttpClientBHttpClientControllerB

DI登録コードは次のようになります。

HttpClient httpClientA = new HttpClient();
httpClientA.BaseAddress = endPointA;
services.AddSingleton<HttpClient>(httpClientA);

HttpClient httpClientB = new HttpClient();
httpClientB.BaseAddress = endPointB;
services.AddSingleton<HttpClient>(httpClientB);

サブクラス化HttpClientしてコントローラーごとに一意の型を作成できることはわかっていますが、それはあまり拡張性がありません。

より良い方法は何ですか?

更新特にHttpClientに関してMicrosoftは作業中に何かを持っているようです

https://github.com/aspnet/HttpClientFactory/blob/dev/samples/HttpClientFactorySample/Program.cs#L32-これを指摘してくれた@ mountain-traveller(Dylan)に感謝します。

ポーク

注:この回答ではとしてHttpClientとを使用してHttpClientFactoryますが、他の種類のものにも簡単に適用できます。特に新しいを使用してから、好ましいです。HttpClientIHttpClientFactoryMicrosoft.Extensions.Http


組み込みの依存性注入コンテナは名前付き依存性登録をサポートしておらず、現時点ではこれを追加する予定はありません

この理由の1つは、依存性注入では、必要な名前付きインスタンスの種類を指定するためのタイプセーフな方法がないことです。コンストラクターのパラメーター属性(またはプロパティインジェクションのプロパティの属性)のようなものを使用することは確かにできますが、それはおそらく価値がない別の種類の複雑さです。そしてそれは確かに型システムによって支えられないでしょう、それは依存性注入がどのように機能するかの重要な部分です。

一般に、名前付きの依存関係は、依存関係を適切に設計していないことを示しています。同じタイプの2つの異なる依存関係がある場合、これはそれらが交換可能に使用される可能性があることを意味するはずです。それが当てはまらず、一方が有効で他方が無効である場合、それはあなたがリスコフの置換原則に違反している可能性があることを示しています

さらに、名前付きの依存関係をサポートする依存性注入に含まれるものを見ると、これらの依存性を取得する唯一の方法は、依存性注入を使用せず、代わりにサービスロケーターパターンを使用することです。これは、DIが促進する制御反転とは正反対です。

より大きな依存性注入コンテナの1つであるSimpleInjectorは、次のような名前付き依存性がないことを説明しています

キーによるインスタンスの解決は、アプリケーションがDIコンテナー自体に多数の依存関係を持つ傾向がある設計に必ずつながるため、SimpleInjectorから意図的に除外されている機能です。キー付きインスタンスを解決するには、Containerインスタンスを直接呼び出す必要があります。これにより、ServiceLocatorのアンチパターンが発生します。

これは、キーによるインスタンスの解決が決して役に立たないという意味ではありません。キーによるインスタンスの解決は、通常、コンテナではなく特定のファクトリのジョブですこのアプローチにより、設計がはるかにクリーンになり、DIライブラリに多数の依存関係をとる必要がなくなり、DIコンテナの作成者が単に考慮しなかった多くのシナリオが可能になります。


とはいえ、このようなものが本当に必要場合があり、多数のサブタイプと個別の登録を行うことは、単に実現可能ではありません。その場合でも、これにアプローチする適切な方法があります。

ASP.NET Coreのフレームワークコードにこれに似たものがあると私が考えることができる特定の状況が1つあります。それは、認証フレームワークの名前付き構成オプションです。概念をすばやく説明しようと思います(我慢してください):

ASP.NET Coreの認証スタックは、同じタイプの複数の認証プロバイダーの登録をサポートしています。たとえば、アプリケーションが使用する可能性のある複数のOpenIDConnectプロバイダーが存在する可能性があります。しかし、それらはすべてプロトコルの同じ技術的実装を共有していますが、それらが独立して機能し、インスタンスを個別に構成する方法が必要です。

これは、各「認証スキーム」に一意の名前を付けることで解決されます。スキームを追加するときは、基本的に新しい名前を登録し、どのハンドラータイプを使用するかを登録に指示します。さらに、各スキームを構成します。IConfigureNamedOptions<T>これを使用して実装すると、基本的に未構成のオプションオブジェクトが渡され、名前が一致した場合に構成されます。したがって、認証タイプごとにT、最終的には複数の登録IConfigureNamedOptions<T>があり、スキームの個々のオプションオブジェクトを構成できます。

ある時点で、特定のスキームの認証ハンドラーが実行され、実際に構成されたオプションオブジェクトが必要になります。このため、IOptionsFactory<T>どのデフォルト実装が具体的なオプションオブジェクトを作成する機能を提供するかによって異なりIConfigureNamedOptions<T>ます。このオブジェクトは、これらすべてのハンドラーによって構成されます。

そして、オプションファクトリのその正確なロジックは、一種の「名前付き依存関係」を実現するために利用できるものです。特定の例に翻訳すると、たとえば次のようになります。

// container type to hold the client and give it a name
public class NamedHttpClient
{
    public string Name { get; private set; }
    public HttpClient Client { get; private set; }

    public NamedHttpClient (string name, HttpClient client)
    {
        Name = name;
        Client = client;
    }
}

// factory to retrieve the named clients
public class HttpClientFactory
{
    private readonly IDictionary<string, HttpClient> _clients;

    public HttpClientFactory(IEnumerable<NamedHttpClient> clients)
    {
        _clients = clients.ToDictionary(n => n.Key, n => n.Value);
    }

    public HttpClient GetClient(string name)
    {
        if (_clients.TryGet(name, out var client))
            return client;

        // handle error
        throw new ArgumentException(nameof(name));
    }
}


// register those named clients
services.AddSingleton<NamedHttpClient>(new NamedHttpClient("A", httpClientA));
services.AddSingleton<NamedHttpClient>(new NamedHttpClient("B", httpClientB));

次に、HttpClientFactoryどこかに挿入し、そのGetClientメソッドを使用して名前付きクライアントを取得します。

明らかに、この実装と私が以前に書いたことについて考えると、これはサービスロケーターパターンに非常に似ています。ある意味では、既存の依存性注入コンテナの上に構築されていますが、この場合は実際には1つです。これはそれをより良くしますか?おそらくそうではありませんが、それは既存のコンテナで要件を実装する方法なので、それが重要です。完全な防御のために、上記の認証オプションの場合、オプションファクトリは実際のファクトリであるため、実際のオブジェクトを構築し、既存の事前登録されたインスタンスを使用しないため、技術的にサービスロケーションパターンではありません


明らかに、他の選択肢は、上記で書いたことを完全に無視し、ASP.NETCoreで別の依存性注入コンテナーを使用することです。たとえば、Autofacは名前付きの依存関係をサポートしておりASP.NETCoreの既定のコンテナーを簡単に置き換えることができます

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

ASP .Net Core WebAPI複数のコンストラクターを使用した依存性注入クラス

分類Dev

ASP.NET Core2.0依存性注入のデフォルトインスタンス

分類Dev

asp.netコア2でのコンストラクター依存性注入

分類Dev

複数のコンストラクターを使用したASP.NETコア依存性注入

分類Dev

Asp.Net Coreで同じインターフェイスの複数の実装を登録する方法

分類Dev

複数のプロジェクトでのasp.net5の依存性注入

分類Dev

複数のプロジェクトでのasp.net5の依存性注入

分類Dev

ASP.netコアでの依存性注入オンザフライ

分類Dev

ASP.NET Core 2.xミドルウェア用のカスタム依存性注入リゾルバー?

分類Dev

抽象クラス、ASP.NETコアでの依存性注入

分類Dev

ASP.NET MVC5のControllerFactoryを使用したコントローラーのコンストラクターでの依存性注入

分類Dev

.NET Coreの依存性注入、汎用インターフェースの解決

分類Dev

ASP.NET Core2タイプMicrosoftEntityFrameworkCoreDbContextのサービスを解決できません

分類Dev

ASP.Net Core2タイプのサービスを解決できません

分類Dev

ASP.NET Coreのシングルトンでは、複数のインスタンスを使用できます

分類Dev

asp.net 5カスタムクラスでの依存性注入、正しい方法は何ですか?

分類Dev

ASP.Net Core2複数のコントローラー

分類Dev

ASP.NET WebAPIの依存性注入

分類Dev

Asp.Net MVC 5 IoC +依存性注入のテスト

分類Dev

ASP.NET Core2の単一のプロパティに対してカスタムモデルバインダーが起動しない

分類Dev

ASP.NET Core2でステータスコード201のファイルを返す

分類Dev

Asp.Net CoreMVCビューでの依存性注入はパフォーマンスに影響しますか

分類Dev

ASP.NETコア依存性注入のライフタイムをオーバーライドする

分類Dev

ASP.NETコアワーカーサービスでの依存性注入

分類Dev

Asp.Net Core2でのトークンベースの認証

分類Dev

HTTPエラー500.35-同じプロセス内のANCM複数のインプロセスアプリケーションASP.NET Core 3

分類Dev

ASP.NET Core 2の依存性注入により例外がスローされる

分類Dev

ASP.NET Core 2の依存性注入により例外がスローされる

分類Dev

ASP.NET Core 2の依存性注入により例外がスローされる

Related 関連記事

  1. 1

    ASP .Net Core WebAPI複数のコンストラクターを使用した依存性注入クラス

  2. 2

    ASP.NET Core2.0依存性注入のデフォルトインスタンス

  3. 3

    asp.netコア2でのコンストラクター依存性注入

  4. 4

    複数のコンストラクターを使用したASP.NETコア依存性注入

  5. 5

    Asp.Net Coreで同じインターフェイスの複数の実装を登録する方法

  6. 6

    複数のプロジェクトでのasp.net5の依存性注入

  7. 7

    複数のプロジェクトでのasp.net5の依存性注入

  8. 8

    ASP.netコアでの依存性注入オンザフライ

  9. 9

    ASP.NET Core 2.xミドルウェア用のカスタム依存性注入リゾルバー?

  10. 10

    抽象クラス、ASP.NETコアでの依存性注入

  11. 11

    ASP.NET MVC5のControllerFactoryを使用したコントローラーのコンストラクターでの依存性注入

  12. 12

    .NET Coreの依存性注入、汎用インターフェースの解決

  13. 13

    ASP.NET Core2タイプMicrosoftEntityFrameworkCoreDbContextのサービスを解決できません

  14. 14

    ASP.Net Core2タイプのサービスを解決できません

  15. 15

    ASP.NET Coreのシングルトンでは、複数のインスタンスを使用できます

  16. 16

    asp.net 5カスタムクラスでの依存性注入、正しい方法は何ですか?

  17. 17

    ASP.Net Core2複数のコントローラー

  18. 18

    ASP.NET WebAPIの依存性注入

  19. 19

    Asp.Net MVC 5 IoC +依存性注入のテスト

  20. 20

    ASP.NET Core2の単一のプロパティに対してカスタムモデルバインダーが起動しない

  21. 21

    ASP.NET Core2でステータスコード201のファイルを返す

  22. 22

    Asp.Net CoreMVCビューでの依存性注入はパフォーマンスに影響しますか

  23. 23

    ASP.NETコア依存性注入のライフタイムをオーバーライドする

  24. 24

    ASP.NETコアワーカーサービスでの依存性注入

  25. 25

    Asp.Net Core2でのトークンベースの認証

  26. 26

    HTTPエラー500.35-同じプロセス内のANCM複数のインプロセスアプリケーションASP.NET Core 3

  27. 27

    ASP.NET Core 2の依存性注入により例外がスローされる

  28. 28

    ASP.NET Core 2の依存性注入により例外がスローされる

  29. 29

    ASP.NET Core 2の依存性注入により例外がスローされる

ホットタグ

アーカイブ