·您现在的位置: 云翼网络 >> 文章中心 >> 网站建设 >> 网站建设开发 >> ASP.NET网站开发 >> Controller的创建
在ControllerBuilder类中设置ControllerFactory,然后使用ControllerFactory创建Controller。 http请求在进入httphandler映射处理时,通过ControllerBuilder的Current获取ControllerFactory,然后使用默认或者注册的(如果注册地话)ControllerFactory创建controller。默认的工厂是一个DefaultControllerFactory对象,由下面代码可以看出。
internal ControllerBuilder(IResolver<IControllerFactory> serviceResolver){ ControllerBuilder controllerBuilder = this; IResolver<IControllerFactory> resolver = serviceResolver; if (resolver == null) resolver = (IResolver<IControllerFactory>) new SingleServiceResolver<IControllerFactory>((Func<IControllerFactory>) (() => this._factoryThunk()),(IControllerFactory) new DefaultControllerFactory() { ControllerBuilder = this }, "ControllerBuilder.GetControllerFactory"); controllerBuilder._serviceResolver = resolver; }
而Controller的产生是通过DefaultControllerFactory的CreateController来实现的,代码如下:
public virtual IController CreateController(RequestContext requestContext, string controllerName){ if (requestContext == null) throw new ArgumentNullException("requestContext"); if (string.IsNullOrEmpty(controllerName)) throw new ArgumentException(MvcResources.Common_NullOrEmpty, "controllerName"); Type controllerType = this.GetControllerType(requestContext, controllerName); return this.GetControllerInstance(requestContext, controllerType);}
然后查看GetControllerType方法:
PRotected internal virtual Type GetControllerType(RequestContext requestContext, string controllerName){ if (string.IsNullOrEmpty(controllerName)) throw new ArgumentException(MvcResources.Common_NullOrEmpty, "controllerName"); object obj; if (requestContext != null && requestContext.RouteData.DataTokens.TryGetValue("Namespaces", out obj)) { IEnumerable<string> enumerable = obj as IEnumerable<string>; if (enumerable != null && Enumerable.Any<string>(enumerable)) { HashSet<string> namespaces = new HashSet<string>(enumerable, (IEqualityComparer<string>) StringComparer.OrdinalIgnoreCase); Type withinNamespaces = this.GetControllerTypeWithinNamespaces(requestContext.RouteData.Route, controllerName, namespaces); if (withinNamespaces != (Type) null || false.Equals(requestContext.RouteData.DataTokens["UseNamespaceFallback"])) return withinNamespaces; } } if (this.ControllerBuilder.DefaultNamespaces.Count > 0) { HashSet<string> namespaces = new HashSet<string>((IEnumerable<string>) this.ControllerBuilder.DefaultNamespaces, (IEqualityComparer<string>) StringComparer.OrdinalIgnoreCase); Type withinNamespaces = this.GetControllerTypeWithinNamespaces(requestContext.RouteData.Route, controllerName, namespaces); if (withinNamespaces != (Type) null) return withinNamespaces; } return this.GetControllerTypeWithinNamespaces(requestContext.RouteData.Route, controllerName, (HashSet<string>) null);}
可以看到最终都归结到同一个方法GetControllerTypeWithinNamespaces中,代码如下:
private Type GetControllerTypeWithinNamespaces(RouteBase route, string controllerName, HashSet<string> namespaces){ this.ControllerTypeCache.EnsureInitialized(this.BuildManager); ICollection<Type> controllerTypes = this.ControllerTypeCache.GetControllerTypes(controllerName, namespaces); switch (controllerTypes.Count) { case 0: return (Type) null; case 1: return Enumerable.First<Type>((IEnumerable<Type>) controllerTypes); default: throw DefaultControllerFactory.CreateAmbiguousControllerException(route, controllerName, controllerTypes); } }
而方法EnsureInitialized()是通过IBuildManager获取程序中所有实现了IController的类型,然后在这些类型里用路由数据或者ControllerBuilder中的命名空间和controller的名称进行匹配,如果没有匹配,返回null,如果有一个匹配,返回,如果有多个,抛出异常!
现在获取到了controllerType的类型,然后返回到工厂的CreateController的最后一步,查看GetControllerInstance方法,代码如下:
protected internal virtual IController GetControllerInstance(RequestContext requestContext, Type controllerType) { if (controllerType == (Type) null) { throw new HttpException(404, string.Format((IFormatProvider) CultureInfo.CurrentCulture, MvcResources.DefaultControllerFactory_NoControllerFound, new object[1] { (object) requestContext.HttpContext.Request.Path })); } else { if (typeof (IController).IsAssignableFrom(controllerType)) return this.ControllerActivator.Create(requestContext, controllerType); throw new ArgumentException(string.Format((IFormatProvider) CultureInfo.CurrentCulture, MvcResources.DefaultControllerFactory_TypeDoesNotSubclassControllerBase, new object[1] { (object) controllerType }), "controllerType"); } }
可以看到,这个时候又使用到了另外一个对象ControllerActivator,由DefaultControllerFactory的构造函数可以看出
internal DefaultControllerFactory(IControllerActivator controllerActivator, IResolver<IControllerActivator> activatorResolver, IDependencyResolver dependencyResolver) { if (controllerActivator != null) this._controllerActivator = controllerActivator; else this._activatorResolver = activatorResolver ?? (IResolver<IControllerActivator>) new SingleServiceResolver<IControllerActivator>((Func<IControllerActivator>) (() => (IControllerActivator) null),(IControllerActivator) new DefaultControllerFactory.DefaultControllerActivator(dependencyResolver), "DefaultControllerFactory constructor"); }
默认使用的是实现了接口IResolver<TService>的SingleServiceResolver<TService>对象默认注册的一个内部对象DefaultControllerActivator,然后调用它的create方法,代码如下:
public IController Create(RequestContext requestContext, Type controllerType) { try { return (IController) (this._resolverThunk().GetService(controllerType) ?? Activator.CreateInstance(controllerType)); } catch (Exception ex) { throw new InvalidOperationException(string.Format((IFormatProvider) CultureInfo.CurrentCulture, MvcResources.DefaultControllerFactory_ErrorCreatingController, new object[1] { (object) controllerType }), ex); } }
而DefaultControllerActivator对象中的属性_resolverThunk是一个Func<IDependencyResolver> _resolverThunk委托对象,我们通过DefaultControllerFactory构造函数中调用的new DefaultControllerFactory.DefaultControllerActivator(dependencyResolver),可以看到DefaultControllerActivator的构造函数
public DefaultControllerActivator(IDependencyResolver resolver){ if (resolver == null) this._resolverThunk = (Func<IDependencyResolver>) (() => DependencyResolver.Current); else this._resolverThunk = (Func<IDependencyResolver>) (() => resolver);}
对它的设置,如果在自己实现的ControllerFactory的构造函数中传递了自己定义的一个IDependencyResolver对象或者DependencyResolver的SetResolver方法设置了一个自定义的IDependencyResolver对象,就会使用它,如果没有,则使用默认的DependencyResolver.Current,可以看到DependencyResolver.Current是一个实现了IDependencyResolver接口对象的引用,从他的构造函数
public DependencyResolver(){ this.InnerSetResolver((IDependencyResolver) new DependencyResolver.DefaultDependencyResolver());}
看出它使用的是一个内部私有的对象DefaultDependencyResolver,
private class DefaultDependencyResolver : IDependencyResolver{ public object GetService(Type serviceType) { if (!serviceType.IsInterface) { if (!serviceType.IsAbstract) { try { return Activator.CreateInstance(serviceType); } catch { return (object) null; } }