ASP.NETのgetServiceにおけるコア()とGetRequiredService差()

記事、「3.0 WPF、.NETのコアで利用IOCグラフィックチュートリアルでは、」我々はWPFのに適用しようと.NET CoreIOC構築されたプログラミング、解析MainWindow私が使用した時間GetRequiredService<T>()の方法がこれだけ考えていたGetRequiredService<T>()とメソッドをGetService<T>()最後にそれは、それ以来、グーグルの一握りを何違いを生むん、その違いを紹介する記事を見つけたので、我々は手助けをしたい、1を翻訳しようとします。最後に、元のリンクを与える、以下では、コンテンツの翻訳です。

著者:ル・ウィッシュに応じて
オリジナル住所:https://www.cnblogs.com/yilezhu/p/11107648.html


この記事では説明Microsoft.Extensions.DependencyInjectionで/ビルトインメソッドASP.NETコアDIコンテナが提供するデフォルトGetService<T>()GetRequiredService<T>()方法を。私はあなたが使用する必要がある方法、それらの間の違いと説明されます。

サービスが存在しない場合はGetService()リターンをnullGetRequiredService()しかし、例外がスローされます。あなたは、サードパーティ製のコンテナを使用している場合は、可能な限り使用GetRequiredService-例外が発生した場合、あなたが期待未登録のサービスを識別できるように、サードパーティ製のコンテナは、異常情報に基づいて診断情報を提供するかもしれない理由

コア・コンテナ - IServiceProviderインターフェイス

ASP.NETコア依存性注入抽象コアIServiceProviderインタフェース。インターフェイスは、実際にはSystem、基本クラスライブラリの名前空間の一部。インターフェース自体は非常に簡単です:

public interface IServiceProvider
{
    object GetService(Type serviceType);
}

あなたはDIコンテナ(使用、使用後はIServiceCollection)すべてのクラスを登録し、ほぼすべてのDIコンテナは必要あなたが許可されてやってGetService()オブジェクトのインスタンスを検索します。

もちろん、あなたは通常、コードから直接使用するべきではありませんIServiceProvider代わりに、標準のコンストラクタ・インジェクションを使用して許可する必要があり、フレームを運ぶと、舞台裏で使用しますIServiceProvider

直接使用するIServiceProvider模範的なサービスロケータモード。これはされ、一般的にアンチパターンであると考えられ、それは依存関係のクラスを隠しているので、。

しかし、時には、あなたは選択の余地がありません。たとえば、あなたがしようとした場合、サービスの属性に注入する、またはDIコンテナを設定するときに「フォワード」タイプを使用して、あなたが直接使用する必要がありますIServiceProvider

getServiceを比較 ()和GetRequiredService ()

私たちは、もはやあなたからしたい場合は、.NET 1.0を使用していないので、IServiceProvider検索サービス、あなたは一般的な、一般的な使用することGetService<T>()ではなく、拡張メソッドをGetService(Type)インターフェイスメソッド。しかし、あなたが同様に気づいたかもしれないGetRequiredService<T>()拡張メソッドを-質問があり、それはあなたが使用されるべき方法を決め、それらの間でどのような違いを作るのですか?

我々はすべてのコードを学ぶ前に、これらの方法の予想される動作について話しましょう。まず、GetService()文書法が開始されます:

GetService()返すserviceTypeサービスオブジェクトの種類を。それが返されるサービスオブジェクトのタイプではない場合serviceTypeが返されますnull

そして、GetRequiredService()文書の内容を比較します:

GetRequiredService()返すserviceTypeサービスオブジェクトの種類を。何も存在しない場合はserviceType、サービスの種類は、それがスローInvalidOperationException例外を。

要求のインスタンス場合したがって、serviceType提供されて、両方の方法の動作は同一です。違いがあることであるserviceType行動が登録されていません。

  • GetService- サービスが登録されていない場合は、リターンnull
  • GetRequiredService-サービスが登録されていない場合は、投げるException例外を。

今、私たちは明確に持っていること、のは、いくつかのコードを見てみましょう。

ではServiceProviderServiceExtensionsクラスMicrosoft.Extensions.DependencyInjection.Abstractionsライブラリは、一般的なバージョンの両方を実装GetService<T>()し、GetRequiredService<T>()次のように、メソッドを:

私は、この記事のコードからいくつかの前提条件チェックを削除した。あなたは完全なコードを表示する場合は、GitHubの上でご確認ください

public static class ServiceProviderServiceExtensions
{
    public static T GetService<T>(this IServiceProvider provider)
    {
        return (T)provider.GetService(typeof(T));
    }

    public static T GetRequiredService<T>(this IServiceProvider provider)
    {
        return (T)provider.GetRequiredService(typeof(T));
    }
}

非ジェネリックバージョンへの一般的な拡張メソッドを委譲-これらのメソッドのどちらも、実際には同じですGetService()GetRequiredService()彼らはただ便利ですので、あなたはあなた自身のコード内の多くを使用する必要はありませんtypeof()し、型変換。

非ジェネリックバージョンGetService()であるIServiceProviderインタフェースの一部が、非一般的なGetRequiredService()実装では、同じクラスの拡張メソッドです:

public static class ServiceProviderServiceExtensions
{
    public static object GetRequiredService(this IServiceProvider provider, Type serviceType)
    {
        var requiredServiceSupportingProvider = provider as ISupportRequiredService;
        if (requiredServiceSupportingProvider != null)
        {
            return requiredServiceSupportingProvider.GetRequiredService(serviceType);
        }

        var service = provider.GetService(serviceType);
        if (service == null)
        {
            throw new InvalidOperationException(Resources.FormatNoServiceRegistered(serviceType));
        }

        return service;
    }
}

この方法の最初のステップはチェックするために設けられているIServiceProviderかどうかを達成しますISupportRequiredServiceこのインタフェースは、基礎となる非汎用的な提供GetRequiredServiceを実現し、そのサービスプロバイダは、それを達成するためならば、GetRequiredService()あなたは直接呼び出すことができます。

ASP.NETコアは、内蔵のDIコンテナはなかった実現ISupportRequiredService-唯一のサードパーティ製の容器を実現しますGetRequiredService()

場合はIServiceProvider達成されなかっISupportRequiredService:ご想像のとおり、その後、実行例外の必要な動作は、スローされますGetService()呼び出し、リターンがあればnullスローされます。

あなたはどちらの方法を使用する必要がありますか?

私が前に言ったように、理想的には、両方がすることができます!

独自のコードを使用してISeviceProvider、使用している通常サービスロケータアンチパターンフラグのを、とても一般的に避けるべきですISeviceProviderもし、しかし、必要な制限を(例えば、設計に起因するあなたはDIでプロパティを使用することはできません)、またはDIコンテナの構成自体の一部として場合、あなたはどちらが行う使用する必要がありますか?

基づいてのGitHub追加する要求GetRequiredService()元の問題、そしてジェレミーD. Miller氏が以前に提起した質問に、私はルールはほとんどの場合だと思います。

使用 GetRequiredService()

  • 重複を減らしますサービスが利用できない場合は、使用してGetRequiredService()すぐに例外をスローします。あなたが使用している場合GetService()、あなたは、呼び出し元のコードかどうかを確認する必要がありnull、通常は例外がスローされる必要があります。空のどこでも繰り返される必要があるコードを確認してください。
  • すぐに失敗します使用している場合GetService()、それは時間であるかどうかをチェックするのを忘れnull、その後あなたのプログラムにありますNullReferenceException終了します。常に明示的にあなたが言うよりも、例外の原因を見つけるInvalidOperationExceptionより困難に、より多くの作業が行われる必要があります。
  • 高度な診断のためのサードパーティ製のコンテナを許可します一つの大きな利点のStructureMapといくつかの他のサードパーティ製のコンテナは、彼らが、詳細な例外メッセージを提供することができるということですなぜサービスを見つけることができません。使用している場合はGetRequiredService()、サードパーティ製の容器自体が例外を生成しますので、コンテナに固有の追加情報を提供することができます。のみを返すnull(とGetService()あなたの更なる詳細を与えることはありません)。これは導入することであるGetRequiredService()主な原因を

もちろん、私は `)(GetRequiredServiceに対するいくつかの引数を見てきましたが、私はそれらのいずれかが審査の対象ではありませんと思います:

  • 「私は、サードパーティ製の使用していないコンテナを」あなたは組み込みのコンテナ(未達成を使用している場合ISupportRequiredService)、あなたは、他の診断の利点を使用することはできませんGetRequiredService()しかし、私は、最初の2つの利点がまだ存在すると思うし、GetRequiredService価値が使用します。後で、サードパーティ製のコンテナを追加した場合また、あなたはすでにベストプラクティスを使用しています。
  • 「私は時々だけでDIコンテナに登録され、オプションのサービスを提供しています。」この可能性は、使用することですGetService()唯一の正当な理由を。あなたのコードは、唯一の特定のサービスを実行するために登録されている場合は、使用する必要があるかもしれませんGetService()あなたはしかし、GetService()NULLを返し、私はまた、それが時にフォールバックサービスを使用し見てきました。私の意見では、これはめったにありませんアプリケーションの良いモデルコード。代替配置ではなく、位置情報サービスの使用より、DIコンテナ構成の一部であるべきです。

だから、今、あなたは持っている- GetService()GetRequiredService()の間のコントラスト。私はさらにそれを掘る前に、私は1とされていない他の選択したとき、私はある程度任意ですが、今私は常に許可された使用のために取ることを確認しますGetRequiredService()

概要

GetService()それはIServiceProvider、上の唯一の方法ISeviceProviderASP.NETコアDIの抽象における中心のインタフェースです。容器はまた、第三のオプションインターフェースに実装されてもよいISupportRequiredService、インタフェース提供GetRequiredService()方法。場合は、要求のタイプはserviceType、これらのメソッドの同じ動作可能です。サービスは(すなわち、それが登録されていない)使用できない場合は、GetService()返すnull、およびGetRequiredService()スローInvalidOperationException

GetRequiredService()GetService()主な利点サービスが利用できないときには、サードパーティの容器は追加の診断情報を提供できることです。これにより、容器を使用する場合、サードパーティを使用することが好ましいですGetRequiredService()個人的に、私は私が唯一の組み込みのDIコンテナを使用している場合でも、どこでもそれを使用します。

英語オリジナルリンク:https://andrewlock.net/the-difference-between-getservice-and-getrquiredservice-in-asp-net-core/

おすすめ

転載: www.cnblogs.com/yilezhu/p/11107648.html