web-dev-qa-db-ja.com

MVCコントローラーのコンストラクターパラメーターはどのように設定されますか?

構造は依存性注入とどのように連携しますか?

次のコードで:

public class AdvancedSearchController : Controller
{
    private EmployeeController _employeeController;

    public AdvancedSearchController(EmployeeController employeeController)
    {
        _employeeController = employeeController;
    }

上記のコードのemployeeControllerはいつ、どのように設定またはコンストラクターに渡されますか?この魔法はどうやって起こりますか?

2
Rodney

依存性注入 マジックを考慮しない限り、マジックはありません。そのアプリの起動/ブートストラップコードを調べれば、ほぼ間違いなく IoCコンテナー が見つかります。 Global.asax.csを調べ、アプリケーション開始イベントハンドラーからのパスをたどります。コンポーネント/サービスの登録はどこかにあります。 Global.asaxにある場合もあれば、App_Startに格納されている場合もあれば、ルートにある場合もあれば、別の場所にある場合もあります。しかし、それはあります。

ASP.NETの最新バージョンには、 組み込みの依存性注入 が付属しています。最新バージョンの MVCで使用可能

古いフレームワークを使用している場合は、サードパーティのコンテナが多数あります。いくつかの例:

原理は簡単です。ある具体的なタイプを契約のアクティブな表現として登録します。 (通常、コントラクトはインターフェイスですが、具象タイプにすることもできます。)コードでは、常にコントラクトとして参照します。コンテナは登録されたタイプを提供しますが、詳細について考える必要はありません。これにより、実装を1か所だけで簡単に交換できます。これにより、予測可能なモックオブジェクトを使用するのではなく、予測できない複雑なオブジェクトを使用するのと同じように、コードのテストを簡単に行うことができます。複雑なオブジェクトは、実際にテストしているものを理解することを困難にします。

IoCコンテナーは、型をコントラクトとして登録するだけでなく、型をマネージコンポーネントに自動的に挿入するなどの高度な機能も備えています。それがあなたの例に見られるものです。コンテナーはコントローラーを管理しているので、EmployeeControllerAdvancedSearchControllerに提供することがわかっています。知るか?多分それはそれを渡す前にEmployeeControllerに他のタイプを注入しました。 (あなたは尋ねませんでしたが、私はコントローラーを渡すことに夢中ではありません。問題があれば言ってください。それを捨ててください。必要な作業を行うコントローラー以外のコントローラーと交換してください。コントローラーはモデルをビューにのみ編成する必要があります。)

一部のコンテナーでは、登録されたタイプの存続期間を決定することもできます-おそらく、それらは使用されるたびにインスタンス化されます。オブジェクトは、Webリクエストの持続期間中留まるかもしれません( Webサービス)、またはおそらく1つだけです。

7
Scant Roger

ASP.NET Core MVCを使用している場合の動作は次のとおりです。Startup.csクラスのConfigureServicesメソッドにタイプを登録する必要があります。 ConfigureServicesメソッドはランタイムによって呼び出され、依存関係注入コンテナーにサービスを追加します。ここで登録しないと、コントローラーが呼び出されたときよりもエラーが発生します。ビルドは続行されますが、そのURLにアクセスするユーザーがコントローラーを起動するとエラーが返されます。オブジェクトが登録されているので、それがコントローラーに注入されます。

では、なぜこれが役立つのでしょうか。 startup.csクラスには、services.AddTransient IEmployeeController、EmployeeController();などのものが必要です。たとえば、偽のデータを使用して何かをテストしたいとします。その1行をservices.AddTransient IEmployeeController、EmployeeControllerFakeData();に変更します。

クラスEmployeeControllerFakeDataには、テストするハードコードされたデータがいくつか含まれます。これで、コンストラクターに注入されるEmployeeControllerFakeDataが登録されました。

テストデータ、Oracleデータ、SQLデータ、ファイルのデータなど、必要な依存関係を取得して登録し、必要な場所に挿入されるようにします。

0
Torres