带区域的MVC 2 Beta DefaultControllerFactory

时间:2009-11-25 18:59:29

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

为什么默认工厂不会返回控制器的全名(带名称空间)? 我正在使用Service Locator和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", ""));

任何人都可以提供帮助吗?谢谢。

2 个答案:

答案 0 :(得分:2)

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

为了使这更容易,DefaultControllerFactory.CreateController()委托给另外两个方法:GetControllerType()和GetControllerInstance()。如果要使用原始控制器分辨率逻辑(例如类型查找)但只是更改实例化类型的方式,请保留CreateController()和GetControllerType()方法,并重写GetControllerInstance()。这已经处理了您正在复制的命名空间查找逻辑,并且会使您的代码变得更加简单。

答案 1 :(得分:0)

[根据列维的回答更新]

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()meothod 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);
 }