ルート登録とControllerFactoryを確認するユニットテストを作成して、特定のURL、特定のコントローラが作成されるようにします。このような何か:Test ControllerFactory(開始前の初期化段階)
Assert.UrlMapsToController("~/Home/Index",typeof(HomeController));
私は著書「プロASP.NET MVC 3の枠組み」から取られたコードを変更した、そしてControllerFactory.CreateController()呼び出しはInvalidOperationExceptionがスローにすることを除いて、それは完璧になるようで、 This method cannot be called during the application's pre-start initialization stage.
私はMVCソースコードをダウンロードし、問題の原因を探してデバッグしました。これはControllerFactoryから参照されるすべてのアセンブリを検索し、潜在的なコントローラを見つけることができます。どこかCreateControllerコールスタックで、具体的なトラブルメーカーの呼び出しはこれです:
internal sealed class BuildManagerWrapper : IBuildManager {
//...
ICollection IBuildManager.GetReferencedAssemblies() {
// This bails with InvalidOperationException with the message
// "This method cannot be called during the application's pre-start
// initialization stage."
return BuildManager.GetReferencedAssemblies();
}
//...
}
I found a SO commentary on this。私はまだ上記のコードを幸せにするために手動で初期化できるものがあるのだろうかと思います。誰でも?
しかし、それがなければ...私はIBuildManagerの実装から呼び出されることに気付くことができません。私はthe possibility of injecting my own IBuildManagerを探検し、私は次のような問題に遭遇した:
- IBuildManagerが
internal
をマークされているので、私はそれからいくつかの他の許可の導出を必要としています。アセンブリSystem.Web.Mvc.Test
には、テストシナリオ用に設計されたMockBuildManager
というクラスがあります。これは完璧です!これは第2の問題を引き起こす。 - 配布可能なMVCは、近くではSystem.Web.Mvc.Testアセンブリ(DOH!)に付属していません。
- MVC配布可能ファイルにSystem.Web.Mvc.Testアセンブリが付属していても、
MockBuildManager
のインスタンスを持つのはソリューションの半分に過ぎません。そのインスタンスをDefaultControllerFactory
に入力する必要もあります。残念ながら、これを達成するためのプロパティ設定ツールにはinternal
(DOH!)とマークされています。要するに
私はMVCフレームワークを「初期化」する別の方法を見つけない限り、私のオプションは今のいずれかにある:
- 私ができるように、完全DefaultControllerFactoryとその依存関係のためのソースコードを複製元の
GetReferencedAssemblies()
問題をバイパスしてください。 - MVCソースコードに基づいて、配布可能なMVCをMVCの自分のビルドに完全に置き換えてください。ほんの数のカップルを使って、
internal
修飾子を削除してください。 (!ぐふダブル)
ところで、私はMvcContrib「TestHelperは」私の目標を達成するための外観を持っていることを知っているが、私は単にコントローラを見つけるためにリフレクションを使用していると思わ - というより取得するために、実際のIControllerFactoryを使用してコントローラータイプ/インスタンス。
このテスト機能が必要な大きな理由は、DefaultControllerFactoryに基づいて、検証したいカスタムコントローラファクトリを作成したことです。
IOCコンテナからコントローラをプルするカスタムコントローラファクトリをテストしようとして、同じ問題が発生しています。だから私の使用例は、コントローラがGetControllerInstance()メソッドのIOCコンテナから正しいコントローラを引っ張っていることを確認することです(プロテクトされているため直接テストできず、明らかにCreateController()を通してしかアクセスできません)。しかし、例外がスローされるため、コードはそれほど遠くには達しません。 – Thierry