我放入了一个包含 MVC 控制器的程序集,我想将其用作 MvcPlayer 函数的目标。
当我尝试渲染页面时,虽然函数输出表明找不到我的控制器。
是否有一种特殊的技术可以让 Composite 注册我添加到 bin 目录的程序集中可用的控制器?
我放入了一个包含 MVC 控制器的程序集,我想将其用作 MvcPlayer 函数的目标。
当我尝试渲染页面时,虽然函数输出表明找不到我的控制器。
是否有一种特殊的技术可以让 Composite 注册我添加到 bin 目录的程序集中可用的控制器?
所以我对能够使用 StructureMap 来解决这个问题的怀疑是有根据的。
StructureMap 是 .NET 的 DI/IoC 工具。不过,您可以使用任何其他 DI/IoC 工具(包括您自己的手动启动工具)以类似的方式解决此问题。
如果您没有使用 StructureMap 的经验,我建议您阅读一些有关它的文档。这是一个很好的视频教程,您可以使用:
以下文章介绍了 StructureMap 并讨论了我用于解决问题的自定义控制器工厂解决方案:
如果您对自定义控制器工厂不太了解,我会阅读以下文章。本文还为您提供了一些很好的线索,让您了解如何进行自己的手动 IoC(而不是使用 StructureMap 等)。
一句警告!在引用具有对先前版本 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 初始化,通常在应用程序启动时完成(有关示例,请参见结构图文档),您可以通过程序集扫描控制器以及控制器约定:
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());