ASP.NET Web Forms Extensibility: Model Binding Value Providers

ASP.NET 4.5 introduced model binding: basically, it is a way for databound controls – Repeater, GridView, ListView, etc – to be fed, not from a datasource control – ObjectDataSource, EntityDataSource, SqlDataSource, etc -, but from a method in the page. This method needs to return a collection, and may have parameters. The problem is: how these parameters get their values? The answer is: through a model binding value provider.

A model binding value provider is a class that implements IValueProvider, and normally is injected through a ValueProviderSourceAttribute-derived attribute. ASP.NET includes some implementations:

If we want, say, to return a value from the Common Service Locator, it’s pretty easy. First, an attribute:

[Serializable]

[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)]

public sealed class ServiceLocatorAttribute : ValueProviderSourceAttribute

{

    private readonly Type serviceType;

    private readonly String key;


    public ServiceLocatorAttribute(Type serviceType, String key = null)

    {

        this.serviceType = serviceType;

        this.key = key;

    }


    public override IValueProvider GetValueProvider(ModelBindingExecutionContext modelBindingExecutionContext)

    {

        return new ServiceLocatorValueProvider(this.serviceType, this.key);

    }

}

And now the actual value provider:

public sealed class ServiceLocatorValueProvider : IValueProvider

{

    private readonly Type serviceType;

    private readonly String key;


    public ServiceLocatorValueProvider(Type serviceType, String key)

    {

        this.serviceType = serviceType;

        this.key = key;

    }


    public Boolean ContainsPrefix(String prefix)

    {

        return true;

    }


    public ValueProviderResult GetValue(String key)

    {

        return new ValueProviderResult(ServiceLocator.Current.GetInstance(this.serviceType, this.key), null, CultureInfo.CurrentCulture);

    }

}

You can even have the ServiceLocatorAttribute implement the IValueProvider interface, I just separated it because conceptually they are different things.

Finally, here’s how we would use it:

public IQueryable<SomeEntity> GetItems([ServiceLocator(typeof(MyComponent), "SomeKey")] MyComponent cmp)

{

    //do something

}

Pretty sleek, don’t you think? Winking smile

Published by

Ricardo Peres

Tech Lead at RedLight Software.

Leave a Reply

Your email address will not be published. Required fields are marked *