MVC ControllerFactory学习笔记

MVC ControllerFactory学习笔记_第1张图片

上面这张图是asp.net mvc的工作流程图,我们可以看到当一个http请求来临时,首先需要经过路由系统,路由系统从中获取一些路由信息,然后ControllerFactory根据所得到的路由信息生成相应的Controller也就是说,ControllerFactory的作用就是根据路由信息生成相应的Controller

1.ASP.NET MVC内置的ControllerFactory—–DefaultControllerFactory

ASP.NET MVC框架中已经给我们提供了内置的ControllerFactory,即DefaultControllerFactory。它首先从routing data中获取到所请求的controller的名字,然后根据该名字去寻找相应的Controller。如果你希望一个类能被ControllerFactory当作Controller并生成需要遵循以下规则:

(1)该类的作用域必须为public

(2)该类必须可被实例化

(3)该类不能是泛型类

(4)该类的名称的结尾必须是Controller (这也是我们常说的约定大于配置)

(5)该类必须实现IController接口

利用DefaultControllerFactory指定命名空间优先级

如果我们希望DefaultControllerFactory在寻找Controller时都优先在指定的命名空间下寻找,我们可以利用它的DefaultNamespaces属性。不多说,看代码就明白了:

 public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);

            ControllerBuilder.Current.DefaultNamespaces.Add("MyNamespace");
        }
    }

我们在Global.asax.cs中的Application_Start方法中添加最后一句代码,ControllerBuilder.Current属性返回的是当前的ControllerFactory(在这里就DefaultControllerFactory实例)。这样,DefaultControllerFactroy在寻找相应的Controller都优先在MyNamespace空间下寻找。如果在MyNamespace空间未找到,则继续在其他命名空间寻找。

2.使用自定义ControllerFactory

如果ASP.NET MVC内置的DefaultControllerFactory无法满足需求的话,我们可以自定义ControllerFactory来替代DefaultControllerFactory

首先,一个ControllerFactory需要实现IControllerFactory接口:

    public interface IControllerFactory
    {
        IController CreateController(RequestContext requestContext, string controllerName);
        SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName);
        void ReleaseController(IController controller);
    }

其中CreateController方法是关键,它定义了一个ControllerFactory是如何根据信息寻找相应的Controller。而GetControllerSessionBehavior定义指定ControllerSession行为,ReleaseController方法则是释放指定Controller

下面来看一个例子吧:

    public class CustomControllerFactory : IControllerFactory
    {
        public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
        {
            //在这里,为了简单,我不管当前http请求信息是什么,都生成HomeController实例。
            Type targetType = typeof(HomeController);
            return (IController)DependencyResolver.Current.GetService(targetType);
        }

        public System.Web.SessionState.SessionStateBehavior GetControllerSessionBehavior(System.Web.Routing.RequestContext requestContext, string controllerName)
        {
            //默认的Session行为
            return SessionStateBehavior.Default;
        }

        public void ReleaseController(IController controller)
        {
            IDisposable disposable = controller as IDisposable;
            if (disposable != null)
            {
                disposable.Dispose();
            }
        }
    }

在这个例子,不管http请求的信息是什么CustomControllerFactory都生成HomeController实例。

接着我们需要在Global.asax.csApplication_Start方法中注册我们自定义的CustomControllerFactory

    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);

            //注册自定义ControllerFactory
            ControllerBuilder.Current.SetControllerFactory(new CustomControllerFactory());      
        }
    }

现在,MVC使用的就是我们自定义的ControllerFactory了:无论请求信息是什么,生成的都是HomeController

你可能感兴趣的:(mvc,asp.net,ASP.NET,MVC4,MVC5)