首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >控制器的asp.net mvc 4依赖解析器

控制器的asp.net mvc 4依赖解析器
EN

Stack Overflow用户
提问于 2013-02-18 03:31:29
回答 1查看 1.9K关注 0票数 1

我正在使用asp.net mvc 4开发多租户mvc应用程序。

我正在为IOC容器使用Autofac,并已将控制器配置为在不同程序集中的每个客户端注册。

当被要求解析时,Autofac将切换出它返回的控制器,这取决于当前的客户端上下文,这是通过查看路由数据来确定的。

我得到一个例外

发现与控制器“Home”匹配的多个类型。

这似乎表明Autofac正在返回多个匹配项,但是仔细检查,似乎MVC甚至没有调用Autofac以获得控制器分辨率。

我可以看到一个请求从IControllerFactory请求DependencyResolver的调用,但从未请求控制器本身。

是否需要在使用依赖解析器的基础上实现自己的控制器工厂?

我已经查看了mvc的源代码,并从我可以告诉DefaultControllerFactory使用依赖解析器和应该解决控制器,但我有困难调试到它,以确切地了解发生了什么。

承租者dll不被主网站引用,而是在生成后复制。

我的global.asax看起来如下: //首先,使用标准// ContainerBuilder创建应用程序级的默认设置,就像您习惯的那样。var builder =新的ContainerBuilder();var appContainer = builder.Build();

代码语言:javascript
运行
复制
// Once you've built the application-level default container, you
// need to create a tenant identification strategy. The details of this
// are discussed later on.
var tenantIdentifier = new RouteDataTenantIdentificationStrategy();

// Now create the multitenant container using the application
// container and the tenant identification strategy.
var mtc = new MultitenantContainer(tenantIdentifier, appContainer);

// Configure the overrides for each tenant by passing in the tenant ID
// and a lambda that takes a ContainerBuilder.

var assemblies = AppDomain.CurrentDomain.GetAssemblies()
    .AsQueryable()
    .Where(a => a.IsDefined(typeof (PluginAssemblyAttribute), false));


foreach (var assembly in assemblies)
{
    var pluginSpecification =
        assembly.GetCustomAttributes(typeof(PluginAssemblyAttribute), false)
            .OfType<PluginAssemblyAttribute>()
            .Single();
    var assembly1 = assembly;
    mtc.ConfigureTenant(pluginSpecification.Tenant, 
        b => b.RegisterControllers(assembly1));
}

DependencyResolver.SetResolver(new AutofacDependencyResolver(mtc));

租户识别策略如下:

代码语言:javascript
运行
复制
public class RouteDataTenantIdentificationStrategy 
    : ITenantIdentificationStrategy
{
    public bool TryIdentifyTenant(out object tenantId)
    {
        tenantId = null;
        var context = HttpContext.Current;
        try
        {
            if (context == null || context.Request == null)
            {
                return false;
            }
        }
        catch (HttpException)
        {
            // This will happen at application startup in MVC3
            // integration since the ILifetimeScopeProvider tries
            // to be resolved from the container at the point where
            // a new AutofacDependencyResolver is created.
            tenantId = null;
            return false;
        }

        var routeData = RouteTable.Routes.GetRouteData(
            new HttpContextWrapper(context));

        if (routeData != null)
            tenantId = routeData.Values.ContainsKey("tenant") ? 
                routeData.Values["tenant"] : null;

        return tenantId != null;
    }
}

编辑:完整的例外是

代码语言:javascript
运行
复制
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()返回了多个名称空间。

有什么办法可以克服这个问题吗?

EN

回答 1

Stack Overflow用户

发布于 2013-02-18 05:32:51

必须在所有路由中指定命名空间:

代码语言:javascript
运行
复制
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中使用主控制器:要么从主站点HomeController重定向到它,要么创建您的自定义路由(从Route继承),然后在其中进行命名空间选择。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14929066

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档