記事、「3.0 WPF、.NETのコアで利用IOCグラフィックチュートリアルでは、」我々はWPFのに適用しようと.NET Core
IOC構築されたプログラミング、解析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()
リターンをnull
、GetRequiredService()
しかし、例外がスローされます。あなたは、サードパーティ製のコンテナを使用している場合は、可能な限り使用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
、上の唯一の方法ISeviceProvider
ASP.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/