8

MVCでは、aModelValidatorProviderがインスタンス化されて呼び出され、リクエストごとにモデルを検証します。これは、DI環境では、作業単位やデータベースコンテキストなど、単一の要求内でスコープが設定されたオブジェクトに依存する可能性があることを意味します。Web APIでは、これは大幅に変更されているようです。リクエストごとにインスタンス化されるのではなくModelValidatorProvider、アプリケーションの起動時に長寿命でインスタンス化されているように見えます。次に、WebAPIはModelValidatorProviderタイプごとの結果をキャッシュします。つまり、ModelValidatorはDIから依存関係を取得できません。

Service Locatorを使用してファクトリを使用するように実装しようとしてModelValidatorいます(自動の「アンチパターン」コメントは使用しないでください)。これにより、各リクエスト内に内部バリデーターオブジェクトを構築できるようになり、コンテナーから依存関係を取得できるようになります。ModelValidatorただし、基本的にシングルトンとしてスコープされているこの内から、現在のリクエストにスコープされた依存関係リゾルバーまたはコンテナーを取得できません。私は使用しようとしましたGlobalConfiguration.Configuration.DependencyResolverが、これはグローバルスコープのサービスのみを返します(ルートスコープから、ここでも言及されています

私はAutofacで作業しているので、autofac固有のソリューションが適しています(たとえば、MVCにはAutofacDependencyResolver.Current、内部で使用するがありますDependencyResolver.GetService)。DependencyResolverWebAPI統合で利用できる同等のものはありません。おそらく、グローバルがグローバルスコープのサービスのみを返すという上記の理由が原因です。

私がこれを(そして私自身の使用のために)行おうとしている理由は、現在存在しないFluentValidationのWebAPI統合を実装するためです。これまでに2つの試みがありましたが、どちらも依存性注入の問題を処理せず、代わりに単一の静的ModelValidatorになります。

私がこれまでに試したこと:

  • 使用GlobalConfiguration.Configuration.DependencyResolver(ルートスコープからオブジェクトを返します)
  • に依存するFunc<IComponentContext>(常にルートコンテキストを返す)

IModelValidatorProviderその後削除された回答では、WebAPI構成からサービスを削除することが提案されました。インターフェイスと実装クラスはすべて内部として定義されているため、これはリフレクションを使用して実行する必要がありましたが、バリデーターの動作が向上しました(ModelValidatorはリクエストごとに構築されたため)。ただし、リフレクションを使用してモデルとモデルのすべてのプロパティのバリデーターをチェックするため、この方法でパフォーマンスが大幅に低下するため、このオプションは使用しません。

Filip Wの回答は、HttpRequestMessageを使用して依存関係スコープを取得することを提案していますが、長寿命のオブジェクト内からこのオブジェクトへのアクセスを提供するようなものは見つかりませんでした。それHttpRequestMessage.Currentが達成できれば、すべてが適切に機能すると思います。

4

1 に答える 1

4

現在の依存関係のスコープを取得するには、の代わりにGetDependencyScope()現在の(サプライズ、サプライズ:)を使用する必要があります(詳細については、MSDNでHttpRequestMessage確認できます)。GlobalConfiguration

少し前に、 Web APIのリクエストごとの依存関係のスコープについてブログを書きましたが、これは役立つはずです。

于 2013-02-22T14:59:38.473 に答える