Simple Injector が Web API コントローラーに依存関係を注入できない

TLTR: この問題は、Web API がコントローラーの型の解決を暗黙的に処理する方法によって引き起こされます。 Web API コントローラーを明示的に登録すると、どこに問題があるかがわかります。

裏で何が起こっているかを順を追って説明します:

<オール>
  • System.Web.Http.DefaultHttpControllerActivator SimpleInjectorWebApiDependencyResolver への呼び出し API コントローラの作成をリクエストします。
  • SimpleInjectorWebApiDependencyResolver その呼び出しを SimpleInjector.Container に転送します インスタンス。
  • その Container ただし、その API コントローラーの明示的な登録はありません (空のコンテナーをリゾルバーに提供したため)。
  • 明示的な登録がないため、コンテナはそのタイプの直前の登録を試みます。
  • ただし、そのコントローラ タイプは、コンテナに登録されていないために解決できないインターフェースに依存します (コンテナが空であることを思い出してください)。
  • コンテナは通常例外をスローしますが、この場合は null が返されます。これは、型が IServiceProvider.GetService を通じて要求されているためです。 メソッドであり、型が明示的に登録されていません。
  • SimpleInjectorWebApiDependencyResolverGetService メソッドは null を返します 同様に、定義上、null を返す必要があるためです。登録が存在しない場合は null を返す必要があります (現在はそうです)。
  • DependencyResolver以来 null を返しました、DefaultHttpControllerActivator これは、その型自体を作成することを意味しますが、これにはコントローラーにデフォルトのコンストラクターが必要です。
  • 簡単に言うと、この問題は、Web API がコントローラーの型の解決を暗黙的に処理する方法によって引き起こされます。

    したがって、ここでの解決策は次のとおりです。

    <オール>
  • Container を 1 つだけ持つ あなたのウェブアプリケーションで。これにより、あらゆる種類の問題や構成の複雑化を防ぐことができます。
  • コンテナにすべての Web API コントローラを明示的に登録します。コントローラーを明示的に登録すると、コントローラーを解決できない場合に Simple Injector が例外をスローすることが保証されます。さらに、これにより container.Verify() を呼び出すことができます これにより、構成が無効な場合、起動時にアプリケーションが失敗します (検証可能な構成が重要です)。また、これにより構成を診断できるため、構成の正確性についてさらに自信が持てます。
  • 私のアドバイスは、MVC と Web API を独自のプロジェクトに配置することです。これにより、作業がはるかに簡単になります。

    すべての Web API コントローラーを登録するには、次のコードを使用します:

    container.RegisterWebApiControllers(GlobalConfiguration.Configuration);
    

    更新:

    このエラーは非常に一般的であるため、SimpleInjectorWebApiDependencyResolver の新しいバージョン クラスは単に決してしません null を返す コントローラ タイプが要求されたとき。代わりに、説明的なエラーがスローされます。このため、公式の SimpleInjectorWebApiDependencyResolver を使用している限り、エラーは表示されません。 .