【问题标题】:MVC 2 Beta DefaultControllerFactory with Areas带有区域的 MVC 2 Beta DefaultControllerFactory
【发布时间】:2010-12-20 10:19:59
【问题描述】:

为什么默认工厂不会返回控制器的全名(带有命名空间)? 我正在使用服务定位器和 autofac。

using System.Web.Mvc;

using Microsoft.Practices.ServiceLocation;

namespace Application.Core.MVC
{

        public override IController CreateController(System.Web.Routing.RequestContext requestContext, string **controllerName**)
        {
            return ServiceLocator.Current.GetInstance<IController>(controllerName);
        }
}

我有两个家庭控制器(一个在区域博客下)

http://localhost/Home

http://localhost/Blog/Home

controllerName 在上面的代码中只返回没有完整限定名的“Home”。 当我尝试为依赖注入注册控制器的名称时,这会产生一个问题。 这是我现在根据这种情况注册控制器的方法。即使这样也毫无例外地调出页面。但是当我访问http://localhost/Home 时,两个控制器都会被调用。

   foreach (var tp in currentAssemblyControllersTypes)
                    builder.Register(tp).FactoryScoped().Named(tp.Name.Replace("Controller", ""));

有人可以帮忙吗?谢谢。

【问题讨论】:

    标签: asp.net-mvc model-view-controller inversion-of-control areas


    【解决方案1】:

    DefaultControllerFactory.CreateController() 方法负责为给定请求返回一个控制器。 controllerName 参数只是路由的 {controller} 部分。 CreateController() 的工作 - 而不是它的调用者 - 找出 URL 中指定的控制器名称的正确类型。

    为了使这更容易,DefaultControllerFactory.CreateController() 委托给另外两个方法:GetControllerType() 和 GetControllerInstance()。如果您想使用原始控制器解析逻辑(例如类型查找)但只是更改类型的实例化方式,请保持 CreateController() 和 GetControllerType() 方法不变,并覆盖 GetControllerInstance()。这已经处理了您正在复制的命名空间查找逻辑,并将使您的代码更加简单。

    【讨论】:

    • 谢谢。我应该只使用 GetControllerInstance()。
    【解决方案2】:

    [根据李维斯的回答更新]

    1.显式注册每个控制器的全名:

     foreach (var tp in currentAssemblyControllersTypes)
                    builder.Register(tp).FactoryScoped().Named(tp.FullName)
    
    //Application.Controllers.HomeController
    //Application.Areas.Blog.Controllers.HomeController
    

    2 .根据PDC09演示为Global.ascx.cs中的Application.Controllers.HomeController在MapRoute()中指定命名空间

        routes.MapRoute(
                        "Default",                                              // Route name
                        "{controller}/{action}/{id}",                           // URL with parameters
                        new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
    
                        ,new string [] { "Application.Controllers"}  //Specify namespace
    
          );
    
            }
    

    3.Override GetControllerInstance()方法IoCControllerFactory.cs

    Protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, System.Type controllerType)
     {
      return (controllerType == null)? base.GetControllerInstance(requestContext,controllerType):ServiceLocator.Current.GetInstance<IController>(controllerType.FullName);
     }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-21
      • 2012-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多