我已经放入包含MVC控制器的程序集中,我想将其用作MvcPlayer函数的目标。MvcPlayer函数 - 如何从导入的程序集引用控制器
当我尝试呈现页面,虽然功能输出状态,我的控制器无法找到。
是否有一种特殊的技术让Composite来注册在我添加到bin目录的程序集中可用的控制器?
我已经放入包含MVC控制器的程序集中,我想将其用作MvcPlayer函数的目标。MvcPlayer函数 - 如何从导入的程序集引用控制器
当我尝试呈现页面,虽然功能输出状态,我的控制器无法找到。
是否有一种特殊的技术让Composite来注册在我添加到bin目录的程序集中可用的控制器?
所以我怀疑能够使用StructureMap来解决这个问题是有根据的。
StructureMap是一个.NET的DI/IoC工具。您可以使用任何其他DI/IoC工具(包括自己开发的手工工具)以类似的方式解决此问题。
如果您对StructureMap没有经验,我会推荐阅读一些关于它的文档。这里是你可以使用一个很好的视频教程:
下面的文章中介绍StructureMap以及有关,我用我的问题定制的控制器工厂解决方案的谈判:
如果你不太了解custom co ntroller工厂,我会阅读以下文章。本文还为您提供了一些关于如何执行自己的手动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 intialisation,通常在应用程序完成启动(例如参见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 /复合定制控制器工厂/ ASPNET/MvcPlayer/Route.cs类:
ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory());
对此的警告。我刚刚将我的站点升级到了Composite 4 Beta 3,它删除了我对Route.cs类所做的所有定制 - 我怀疑更新只是用新版本进行了新的替换。有些事情要注意。 – ctrlplusb 2013-04-16 09:12:04
我开始怀疑您需要注册您自己的ControllerFactory来解决您的控制器。可以使用StructureMap(或您选择的依赖注入器)来执行此操作。其中的示例是:http://weblogs.asp.net/shijuvarghese/archive/2008/10/10/asp-net-mvc-tip-dependency-injection-with-structuremap.aspx 我试过这样做我自己,但目前正在遇到其他问题。我认为它可能与被引用的各种版本的MVC有关。我会在完成后发布进度。 – ctrlplusb 2013-03-15 16:55:59