控制器的啟用預設情況下使用反射來實現的,這其中採用了DI,單例等設計模式。對於控制器的主要涉及到如下的類:
ControllerBuilder、DefaultControllerFactory、DefaultControllerActivator(實現了IControllerActivator介面)、DependencyResolver(並沒有實現IDependencyResolver,但是有這個介面物件例項)、DefaultDependencyResolver(實現了IDependencyResolver介面,預設採用此類來解析控制器物件)
如上的幾個類是控制器啟用最重要的類。大概說說過程,備忘,當然也說不了多具體,有個大概思路就好,網上已經很多介紹的文章了。DefaultControllerFactory並不是構造控制器的地方,控制器的構造實在ControllerBuilder中,具體涉及到SetControllerFactory以及GetControllerFactory兩個方法,我們可以通過SetControllerFactory來擴充自己的IOC容器,這是第一個可供擴充點。
DefaultControllerActivator類用來啟用控制器,我們一般建立自己的MVC框架的時候,都是在這個類實現的ICOntrollerActivator介面的Create方法中,通過獲取的控制器物件使用反射來建立控制器例項。當然這是在我們自己建立自己的MVC框架以及不使用第三方IOC容器的時候,就是使用該方法來建立的,而在MVC框架中,控制器例項的建立是延遲到了efaultDependencyResolver類中。這也是第二個可擴充的地方,我們可以在第三方IOC容器中,實現IControllerActivator介面來建立控制器物件。
DefaultDependencyResolver類實現了IDependencyResolver介面,預設的MVC框架實現的IOC容器(基於DI模式)設計的容器。我們就是在這裡構造了我們的IOC容器,不過通過閱讀原始碼你會發現,該IOC容器原始碼其實就是預設使用反射來建立控制器物件。這與上面的DefaultControllerActivator類的作用是一樣的。可以參考原始碼:
public IController Create(RequestContext requestContext, Type controllerType) { try { return (IController)(_resolverThunk().GetService(controllerType) ?? Activator.CreateInstance(controllerType)); } catch (Exception ex) { throw new InvalidOperationException( String.Format( CultureInfo.CurrentCulture, MvcResources.DefaultControllerFactory_ErrorCreatingController, controllerType), ex); } }
可以看到上面的try語句裡面的程式碼,通過呼叫GetService()方法,預設使用MVC自己的IOC容器(即DefaultDependencyResolver類)。在這裡我們可以基於第三方的IOC來擴充我們自己的設計邏輯,這也是第三個可擴充點。
<<asp.net mvc5框架揭祕>>一書中詳細說了三個可擴充的地方就是如上的描述。上面的描述就是我自己看原始碼以及資料的一個總結,當你看MVC原始碼的時候,你會有自己的收穫,我也沒有全部鋪開來,僅僅就是自己的心得筆記。