ControllerBuilder()
用于激活Controller对象的ControllerFactory最终通过SystemWebMvcControllerBuilder注册到ASPNET MVC应用中如下面的代码所示ControllerBuilder定义了一个静态只读属性Current返回当前ControllerBuilder对象这是针对整个Web应用的全局对象两个SetControllerFactory方法重载用于注册ControllerFactory的类型或者实例而GetControllerFactory方法返回一个具体的ControllerFactory对象
public class ControllerBuilder
{
public IControllerFactory GetControllerFactory()
public void SetControllerFactory(Type controllerFactoryType)
public void SetControllerFactory(IControllerFactory controllerFactory)
public HashSet<string> DefaultNamespaces { get; }
public static ControllerBuilder Current { get; }
}
具体来说如果我们注册的是ControllerFactory的类型那么GetControllerFactory在执行的时候会通过对注册类型的反射(调用Activator的静态方法CreateInstance)来创建具体的ControllerFactory(系统不会对创建的Controller进行缓存)如果注册的是一个具体的ControllerFactory对象该对象直接从GetControllerFactory返回
通过第章URL路由的介绍我们知道被ASPNET路由系统进行拦截处理后会生成一个用于封装路由信息的RouteData对象而目标Controller的名称就包含在通过该RouteData的Values属性表示的RouteValueDictionary对象中对应的Key为controller而在默认的情况下这个作为路由数据的名称只能帮助我们解析出Controller的类型名称如果在不同的命名空间下定义了多个同名的Controller类会导致激活系统无法确定具体的Controller的类型从而抛出异常
为了解决这个问题我们必须为定义了同名Controller类型的命名空间设置不同的优先级具体来说有两种提升命名空间优先级的方式第一种方式就是在调用RouteCollection如下所示的扩展方法MapRoute时指定一个命名空间的列表通过第章URL路由的介绍我们知道通过这种方式指定的命名空间列表会保存在Route对象的DataTokens属性表示的RouteValueDictionary字典中对应的Key为Namespaces
public static class RouteCollectionExtensions
{
//其他成员
public static Route MapRoute(this RouteCollection routes string name
string url string[] namespaces)
public static Route MapRoute(this RouteCollection routes string name
string url object defaults string[] namespaces)
public static Route MapRoute(this RouteCollection routes string name
string url object defaults object constraints string[] namespaces)
}
另一种提升命名空间优先级的方式就是将其添加到当前的ControllerBuilder中的默认命名空间列表中从上面的给出的ControllerBuilder的定义可以看出它具有一个HashSet<string>类型的只读属性DefaultNamespaces代表了这么一个默认命名空间列表对于这两种不同的命名空间优先级提升方式前者(通过路由注册)指定命名空间具有更高的优先级
实例演示如何提升命名空间的优先级(SSS)
[] []