Controller類型的解析()
激活目標Controller對象的前提是能夠正確解析出Controller類型對於DefaultControllerFactory來說用於解析目標Controller類型的輔助信息包括通過與當前請求匹配的路由對象生成的RouteData(其中包含Controller的名稱和命名空間)和包含在當前ControllerBuilder中的命名空間很多讀者可能首先想到的是通過Controller名稱得到對應的類型並通過命名空間組成Controller類型的全名最後遍歷所有程序集並以此名稱去加載相應的類型即可
這貌似是一個不錯的解決方案實際上則完全行不通不要忘了作為請求地址URL一部分的Controller名稱是不區分大小寫的而類型名稱則是大小寫敏感的此外不論是注冊路由時指定的命名空間還是當前ControllerBuilder的默認命名空間有可能包含統配符(*)由於我們不能通過給定的Controller名稱和命名空間得到Controller的真實類型名稱自然就不可能通過名稱去解析Controller的類型了
ASPNET MVC的Controller激活系統則反其道而行之它先遍歷通過BuildManager的靜態方法GetReferencedAssemblies方法得到所有引用程序集通過反射的方式得到定義在它們中的所有實現了接口IController的類型最後通過Controller的名稱和命名空間作為匹配條件去選擇對應的Controller類型
實例演示創建一個自定義ControllerFactory模擬Controller默認激活機制(S)
為了讓讀者對默認采用的Controller激活機制尤其是Controller類型的解析機制有一個深刻的認識通過一個自定義的ControllerFactory來模擬其中的實現由於采用反射的方式來創建Controller對象所以將該自定義ControllerFactory起名為ReflectedControllerFactory
public class ReflectedControllerFactory : IControllerFactory
{
//其他成員
private static List<Type> controllerTypes;
static ReflectedControllerFactory()
{
controllerTypes = new List<Type>()
foreach (Assembly assembly in BuildManagerGetReferencedAssemblies())
{
controllerTypesAddRange(assemblyGetTypes()Where(
type => typeof(IController)IsAssignableFrom(type)))
}
}
public IController CreateController(RequestContext requestContext
string controllerName)
{
Type controllerType = thisGetControllerType(requestContextRouteData
controllerName)
if (null == controllerType)
{
return null;
}
return (IController)ActivatorCreateInstance(controllerType)
}
[] []
From:http://tw.wingwit.com/Article/program/net/201311/16085.html