在MVC框架中存在一些默认的值提供程序模板,这些值提供程序都是通过工厂模式类创建;在MVC框架中存在需要已Factory结尾的工厂类,在值提供程序中也存在ValueProviderFactories工厂类,这个类管理着许多的值提供的工厂;
public static class ValueProviderFactories { private static readonly ValueProviderFactoryCollection _factories = new ValueProviderFactoryCollection() { new ChildActionValueProviderFactory(), new FormValueProviderFactory(), new JsonValueProviderFactory(), new RouteDataValueProviderFactory(), new QueryStringValueProviderFactory(), new HttpFileCollectionValueProviderFactory(), new JQueryFormValueProviderFactory() }; public static ValueProviderFactoryCollection Factories { get { return _factories; } } }
在ControllerBase类中的ValueProvider值默认也是通过ValueProviderFactories类中Factories集合中的值提供工厂创建的;在获取IValueProvider 时是按照_factories 集合中添加的顺序遍历的,也就是说_factories 中的顺序决定了优先采用哪个值提供程序;
ControllerBase.cs
public IValueProvider ValueProvider { get { if (_valueProvider == null) { _valueProvider = ValueProviderFactories.Factories.GetValueProvider(ControllerContext); } return _valueProvider; } set { _valueProvider = value; } }
在ValueProviderFactories的ValueProviderFactoryCollection集合中默认添加的几个工厂类
ChildActionValueProviderFactory:获取子action中的值提供程序的工厂;工厂创建ChildActionValueProvider类;ChildActionValueProvider类继承DictionaryValueProvider<object>,处理子Action(子Action是在某个View中被调用生成某个部分的HTML,类似产生Partial View的Action)时提供值,与RouteDataValueProviderd都是以object为类型的value,同样从ControllerContext的Routedata提取值,Routedata的value(实际上是RouteValueDictionary类型)作为ChildActionValueProvider的数据容器字典,ChildActionValueProvider与RouteDataValueProvider的区别在于GetValue方法,RouteDataValueProvider是根据RouteValueDictionary的键值对去匹配,而ChildActionValueProvider是从它本身的字典集中,已一个GUID值作为key对应的value里面去取值,这个GUID是ChildActionValueProvider的一个静态属性,以这个key获取的value,本身是一个字典集,这个字典集的每一对key/value都存在于ChildActionValueProvider本身的键值对容器中,相当于以GUID为key的value作为了一个副本。
FormValueProviderFactory:获取表单提交中的值提供程序的工厂;工厂创建FormValueProvider类;
JsonValueProviderFactory:获取json字符串中的值提供程序的工厂;工厂创建DictionaryValueProvider类;
RouteDataValueProviderFactory:获取路由Data中的值提供程序的工厂;工厂创建RouteDataValueProvider类;
QueryStringValueProviderFactory:获取QueryString集合中的值提供程序的工厂;工厂创建QueryStringValueProvider类;
HttpFileCollectionValueProviderFactory:获取Http文件中的值提供程序的工厂;工厂创建HttpFileCollectionValueProvider类;
JQueryFormValueProviderFactory:获取JQueryForm中的值提供程序的工厂;工厂创建JQueryFormValueProvider类;
这些工厂类都继承了ValueProviderFactory类,这个类是一个抽象类,他的作用提供了一个根据控制器上下文(ControllerContext)来创建各种的ValueProvider,具体的创建的工作则交给他的继承类来实现;
public abstract class ValueProviderFactory { public abstract IValueProvider GetValueProvider(ControllerContext controllerContext); }
在网上找到了一张接口类库之间的关系图,但是这张图上有个错误,QueryStringValueProvider类实际是继承了NameValueCollectionValueProvider类,而不是DictionaryValueProvider类;而ChildActionValueProvider继承了DictionaryValueProvider类而不是NameValueCollectionValueProvider类;