MvcPlayer 関数のターゲットとして使用したい MVC コントローラーを含むアセンブリをドロップしました。
ページをレンダリングしようとすると、関数の出力にコントローラーが見つからないことが示されます。
bin ディレクトリに追加するアセンブリ内で利用可能なコントローラーを登録するために Composite を取得するための特別な手法はありますか?
MvcPlayer 関数のターゲットとして使用したい MVC コントローラーを含むアセンブリをドロップしました。
ページをレンダリングしようとすると、関数の出力にコントローラーが見つからないことが示されます。
bin ディレクトリに追加するアセンブリ内で利用可能なコントローラーを登録するために Composite を取得するための特別な手法はありますか?
したがって、StructureMapを使用してこの問題を解決できるという私の疑念は十分に根拠がありました。
StructureMapは、.NET用のDI/IoCツールです。ただし、他のDI / IoCツール(独自の手動クランクを含む)を使用して、同様の方法でこの問題を解決することができます。
StructureMapの経験がない場合は、StructureMapに関するドキュメントを読むことをお勧めします。これがあなたが使うことができる良いビデオチュートリアルです:
次の記事では、StructureMapを紹介するとともに、問題に使用したカスタムコントローラーファクトリソリューションについて説明します。
また、カスタムコントローラーファクトリーについてよく知らない場合は、次の記事をお読みください。この記事では、(StructureMapなどを使用する代わりに)独自の手動クランクIoCを実行する方法についてのいくつかの良い手がかりも提供します。
警告の言葉!以前のバージョンのMVC3への明示的な参照があるライブラリを参照するときに問題が発生する可能性があります。私が知る限り、Composite C1 v4.0 beta2とMvcPlayer関数は、MVC4とそれに関連するライブラリに依存しています。バージョンの競合から保護するには、参照が常に正しいバージョンを対象とするように、web.configに次のセクションを追加します。
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers"
publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc"
publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="4.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages"
publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
さて、これでスピードが出てきたので、StructureMapアプローチを採用するために必要なすべてのコードを以下に示します。
StructureMapコントローラーの規則があります。
public class ControllerConvention : ITypeScanner
{
public void Process(Type type, PluginGraph graph)
{
if (typeof(IController).IsAssignableFrom(type) && !type.IsAbstract && !type.IsGenericType)
{
graph.AddType(typeof(IController), type, type.Name.Replace("Controller", "").ToLower());
}
}
}
コントローラーの規則は、StructureMapにMVCコントローラークラスを見つける方法を指示します。これは、IControllerインターフェイスを実装するクラスを探すだけでよいので簡単です。
通常、アプリの起動時に行われるStructureMapの初期化の場合(例については、structuremapのドキュメントを参照)、アセンブリを通過して、コントローラーとコントローラーの規則をスキャンできます。
var controllerAssemblies = new List<Assembly>()
{
typeof(YourController).Assembly,
typeof(AnotherController).Assembly
};
ObjectFactory.Initialize(initialization =>
{
initialization.Scan(scan =>
{
foreach (var assembly in controllerAssemblies)
{
scan.Assembly(assembly);
}
scan.With<ControllerConvention>();
});
});
次に、カスタムコントローラーファクトリが必要になります。
public class StructureMapControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(Type controllerType)
{
try
{
return ObjectFactory.GetInstance(controllerType) as Controller;
}
catch (StructureMapException)
{
System.Diagnostics.Debug.WriteLine(ObjectFactory.WhatDoIHave());
throw;
}
}
}
最後に、カスタムコントローラーファクトリの使用をApp_Code / Composite / AspNet / MvcPlayer/Route.csクラスに登録する必要があります。
ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory());