ASP.NET MVC 4框架揭秘:Controller类型(1)[1]
Controller类型的解析( )
激活目标Controller对象的前提是能够正确解析出Controller类型 对于DefaultControllerFactory来说 用于解析目标Controller类型的辅助信息包括 通过与当前请求匹配的路由对象生成的RouteData(其中包含Controller的名称和命名空间)和包含在当前ControllerBuilder中的命名空间 很多读者可能首先想到的是通过Controller名称得到对应的类型 并通过命名空间组成Controller类型的全名 最后遍历所有程序集并以此名称去加载相应的类型即可
这貌似是一个不错的解决方案 实际上则完全行不通 不要忘了作为请求地址URL一部分的Controller名称是不区分大小写的 而类型名称则是大小写敏感的 此外 不论是注册路由时指定的命名空间还是当前ControllerBuilder的默认命名空间 有可能包含统配符(*) 由于我们不能通过给定的Controller名称和命名空间得到Controller的真实类型名称 自然就不可能通过名称去解析Controller的类型了
ASP NET 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 BuildManager GetReferencedAssemblies())
{
controllerTypes AddRange(assembly GetTypes() Where(
type => typeof(IController) IsAssignableFrom(type)))
}
}
public IController CreateController(RequestContext requestContext
string controllerName)
{
Type controllerType = this GetControllerType(requestContext RouteData
controllerName)
if (null == controllerType)
{
return null;
}
return (IController)Activator CreateInstance(controllerType)
}
lishixinzhi/Article/program/net/201311/16085