目前我有一个相当复杂的项目在进行中,作为其中的一部分,我有一个MEF层,它纯粹处理插件的加载,然后新加载的插件暴露它们的路由,这些路由注册到asp.mvc中,它们的控制器被添加到Ninject的绑定中。
然而,当动态添加的路由被命中(并且它们被命中,我已经用路由调试器检查过了)时,即使在路由中正确地为插件添加了名称空间,问题也会出现。当我说我已经添加了名称空间时,我的意思如下:
var namespaces = new [] { "MyPlugin.Controllers" };
routeCollection.MapRoute(
PluginRoute, "plugin/{action}",
new { controller = "Plugin", action = "Default" },
namespaces);为了给这种情况提供更多的上下文,我继承了NinjectHttpApplication,不做任何其他事情,没有自定义的控制器工厂,没有自定义的依赖解析器,这就是Ninject给我的。然后,我获取当前活动的内核,将其提供给插件,它们会自行注册。
现在命中的路由不起作用了,我只是为任何外部路由得到了一个404,即使它们被命中了,控制器(是的,三重选中)已经注册到了Ninject内核。所以我在想,尽管Ninject已经注册了该类型,但Mvc的DefaultControllerFactory在调用时无法找到该类型:
GetControllerTypeWithinNamespaces(string controllerName, HashSet<string> namespaces)不过,目前让我困惑的一件事是,即使使用正确的名称空间,它也找不到它……然而,为了证明我的假设,如果我将插件作为引用添加到asp mvc项目中并运行它(不更改任何代码,只有插件程序集是项目中的引用,所以它将最终位于bin目录中),它将工作。命中路线,我得到想要的输出...
所以在这一点上,我想知道虽然MEF托管了外部AppDomain,但它并没有以某种方式与当前的DLL或其他东西共享它。这似乎很奇怪..。
这对我来说是一个障碍,所以任何建议都是很棒的!
发布于 2011-12-02 23:31:11
DefaultControllerFactory似乎不知道哪种类型负责处理请求。您必须找出DefaultControllerFactory不知道这些控制器的原因,或者提供您自己的能够处理这些情况的实现。这个问题肯定是与MEF有关的,而不是与Ninject有关的。
public class MyControllerFactory : DefaultControllerFactory
{
public override IController CreateController(RequestContext requestContext, string controllerName)
{
Type controllerType = this.GetControllerType(requestContext, controllerName) ?? this.GetPluginControllerType(requestContext, controllerName)
return this.GetControllerInstance(requestContext, controllerType);
}
private Type GetPluginControllerType(RequestContext requestContext, string controllerName)
{
// put your own implementation here
}
}另一种解决方案是使用Ninject的程序集加载机制而不是MEF。
发布于 2011-10-21 11:04:50
听起来与mef相关,当你自己尝试直接从内核实例化这些类时会发生什么?如果它可以工作,你可以创建你自己的控制器工厂:
public class NinjectControllerFactory : DefaultControllerFactory
{
private IKernel _kernel;
public NinjectControllerFactory(IKernel kernel)
{
_kernel = kernel;
}
protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
{
if (controllerType == null)
return null;
return (IController)_kernel.Get(controllerType);
}
}虽然现在有了MVC3,但我不再为控制器工厂而烦恼,而是进入依赖解析器级别。
public class NinjectDependencyResolver : IDependencyResolver
{
private IKernel _kernel;
public NinjectDependencyResolver(IKernel kernel)
{
_kernel = kernel;
}
public object GetService(Type serviceType)
{
return _kernel.TryGet(serviceType);
}
public System.Collections.Generic.IEnumerable<object> GetServices(Type serviceType)
{
return _kernel.GetAll(serviceType);
}
}注:两者都需要分别在application_start中注册(尽管您只需要使用一个)
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory(_kernel));
DependencyResolver.SetResolver(new NinjectDependencyResolver(_kernel));https://stackoverflow.com/questions/7568078
复制相似问题