Value Providers
ASP.NET MVC 2 introduced a new method to find value providers: the ValueProviderFactory class. Value providers are used by the model binding system in MVC to populate the values of model objects. MVC includes value providers for several common value sources (including query string, form, route data, uploaded files, and JSON postbacks); MVC Futures includes several mode (including cookies, server values, session values, and temp data values). In ASP.NET MVC 3, we have made ValueProviderFactory instances findable via the dependency resolver.
Disclaimer
This blog post talks about ASP.NET MVC 3 Beta, which is a pre-release version. Specific technical details may change before the final release of MVC 3. This release is designed to elicit feedback on features with enough time to make meaningful changes before MVC 3 ships, so please comment on this blog post or contact me if you have comments.
Implementing ValueProviderFactory
Developers who implement this class must provide an implementation of GetValueProvider which, given a controller context, optionally returns an instance of a class which implements the IValueProvider interface. The developer may also choose to return null if there is no appropriate value provider or values.
For reference purposes, there are several implementations of ValueProviderFactory in the MVC and MVC Futures source code. For a simple example, see the pair of classes: QueryStringValueProviderFactory and QueryStringValueProvider.
Implementing IValueProvider
Developers who implement this interface provide implementations of two methods: ContainsPrefix and GetValue. The former method is used to determine if there are any values in the provider with the given prefix (so the model binding system knows when to stop recursively binding). The latter method is used to get the value for a specific key.
There are two implementations of IValueProvider (NameValueCollectionValueProvider and DictionaryValueProvider) will accept collections of values to be used for the value provider implementation. Most of the value providers in the MVC source code actually derive from one of these two base classes.
Location: ValueProviderFactory
This is a “multiply registered” style service introduced in MVC 2. The static registration point for this service is atValueProviderFactories.Factories for non-DI users.
The logic in ValueProviderFactoryCollection (which implements ValueProviderFactories.Factories) was updated to consult the dependency resolver, calling GetServices(typeof(ValueProviderFactory)) and adding any services found to the list of statically registered services. Value providers all collaborate to provide values for model binding, with a “first one to provide the value wins” strategy, so registration order is important. The factories found in the dependency resolver will always run in the order they are returned from the resolver (and before the statically registered value provider factories); similarly, the value providers will be consulted in the order they are returned from the factories.
What’s Next?
Next up we’ll talk about Model Binders.