ASP.NET MVC學習筆記-----ControllerFactory


  上面這張圖是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定義指定Controller的Session行為,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.cs的Application_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。

 

    

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM