Asp.net mvc 4 用于控制器的asp.net mvc 4依赖项解析程序
我正在使用asp.NETMVC4开发一个多租户mvc应用程序 我将Autofac用于IOC容器,并已将控制器配置为在不同程序集中为每个客户端注册 Autofac将根据当前的客户端上下文(通过查看路由数据确定),在被要求解析时切换返回的控制器 我有个例外 找到多个与名为“Home”的控制器匹配的类型 这似乎表明Autofac返回了不止一个匹配项,但仔细观察,MVC似乎甚至没有调用Autofac以获得控制器分辨率 我可以看到一个调用,该调用从Asp.net mvc 4 用于控制器的asp.net mvc 4依赖项解析程序,asp.net-mvc-4,controller,inversion-of-control,autofac,service-locator,Asp.net Mvc 4,Controller,Inversion Of Control,Autofac,Service Locator,我正在使用asp.NETMVC4开发一个多租户mvc应用程序 我将Autofac用于IOC容器,并已将控制器配置为在不同程序集中为每个客户端注册 Autofac将根据当前的客户端上下文(通过查看路由数据确定),在被要求解析时切换返回的控制器 我有个例外 找到多个与名为“Home”的控制器匹配的类型 这似乎表明Autofac返回了不止一个匹配项,但仔细观察,MVC似乎甚至没有调用Autofac以获得控制器分辨率 我可以看到一个调用,该调用从依赖解析程序请求IControllerFactory,但从
依赖解析程序
请求IControllerFactory
,但从未请求控制器本身
我是否需要在使用依赖项解析器的过程中实现自己的控制器工厂
我浏览了mvc的源代码,从中可以看出,DefaultControllerFactory
使用dependencyresolver并应该解析控制器,但我在调试它以查看到底发生了什么方面遇到了困难
主网站未引用租户DLL,而是在生成后复制
我的global.asax
如下所示:
//首先,使用标准
//集装箱建造商,就像你习惯的那样。
var builder=new ContainerBuilder();
var appContainer=builder.Build()
编辑:完全异常为
The request for 'Home' has found the following matching controllers:
MultiTenantViewEngine.Web.Controllers.HomeController
MultiTenantViewEngine.Web.Tenant1.Controllers.HomeController]
System.Web.Mvc.DefaultControllerFactory.GetControllerTypeWithinNamespaces(RouteBase route, String controllerName, HashSet`1 namespaces) +230
System.Web.Mvc.DefaultControllerFactory.GetControllerType(RequestContext requestContext, String controllerName) +833
System.Web.Mvc.DefaultControllerFactory.System.Web.Mvc.IControllerFactory.GetControllerSessionBehavior(RequestContext requestContext, String controllerName) +196
System.Web.Mvc.MvcRouteHandler.GetSessionStateBehavior(RequestContext requestContext) +267
System.Web.Mvc.MvcRouteHandler.GetHttpHandler(RequestContext requestContext) +61
System.Web.Mvc.MvcRouteHandler.System.Web.Routing.IRouteHandler.GetHttpHandler(RequestContext requestContext) +44
System.Web.Routing.UrlRoutingModule.PostResolveRequestCache(HttpContextBase context) +352
System.Web.Routing.UrlRoutingModule.OnApplicationPostResolveRequestCache(Object sender, EventArgs e) +144
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +239
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +114
更深入地观察这一点,似乎表明发生此错误是因为GetControllerTypeWithinNamespaces()返回多个命名空间
有没有办法克服这个问题?您必须在所有路由中指定名称空间:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" }, // Parameter defaults
"Some.NameSpace.To.Controllers" // required
);
如果要在租户DLL中使用主控制器:从主站点重定向到主控制器,或者创建自定义路由(从路由继承)并在其中选择命名空间。RoutedStatenantIdentificationStrategy是什么样子的,你有没有在它里面放一个断点,看看当控制器被解析时它是否被调用?刚刚添加的断点,会再次检查它是否被调用。它是否被调用并返回正确的租户。如果你还没有,你应该看看Zack Owens关于这个的文章。是的,我看到这可能是我最终会走的路线,这取决于应用程序的上下文我要么想在主站点dll中使用控制器,要么在租户1 dll或其他租户dll中使用控制器,因此,最好编写自己的控制器工厂,只要求依赖项解析程序为我提供类型?我宁愿使用自定义路由,因为路由决定加载哪个控制器。ControllerFactory就是这样的:一个工厂正在构建它所订购的控制器。我可以动态重写名称空间来搜索自定义路由吗?
The request for 'Home' has found the following matching controllers:
MultiTenantViewEngine.Web.Controllers.HomeController
MultiTenantViewEngine.Web.Tenant1.Controllers.HomeController]
System.Web.Mvc.DefaultControllerFactory.GetControllerTypeWithinNamespaces(RouteBase route, String controllerName, HashSet`1 namespaces) +230
System.Web.Mvc.DefaultControllerFactory.GetControllerType(RequestContext requestContext, String controllerName) +833
System.Web.Mvc.DefaultControllerFactory.System.Web.Mvc.IControllerFactory.GetControllerSessionBehavior(RequestContext requestContext, String controllerName) +196
System.Web.Mvc.MvcRouteHandler.GetSessionStateBehavior(RequestContext requestContext) +267
System.Web.Mvc.MvcRouteHandler.GetHttpHandler(RequestContext requestContext) +61
System.Web.Mvc.MvcRouteHandler.System.Web.Routing.IRouteHandler.GetHttpHandler(RequestContext requestContext) +44
System.Web.Routing.UrlRoutingModule.PostResolveRequestCache(HttpContextBase context) +352
System.Web.Routing.UrlRoutingModule.OnApplicationPostResolveRequestCache(Object sender, EventArgs e) +144
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +239
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +114
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" }, // Parameter defaults
"Some.NameSpace.To.Controllers" // required
);