How do you take the values posted by an HTML form and turn them into a populated domain entity? One popular technique is to bind the POST values to a view-model and then map the view-model values to an entity. Since your action method’s argument is the view-model, it allows you to decide in the controller code if the view-model is a new entity or an existing one that should be retrieved from the database. If the view-model represents a new entity you can directly create the entity from the view-model values and then call your repository in order to save it.  In the update case, you can directly call your repository to get a specific entity and then update the entity from the values in the view-model

However, this method is somewhat tedious for simple cases. Is a view-model always necessary? Wouldn’t it be simpler to have a model binder that simply created the entity for you directly? Here’s our attempt at such a binder:

public class EntityModelBinder : DefaultModelBinder, IAcceptsAttribute
{   
readonly IRepositoryResolver repositoryResolver;
    EntityBindAttribute declaringAttribute;

    public EntityModelBinder(IRepositoryResolver repositoryResolver)
    {
        this.repositoryResolver = repositoryResolver;
    }

    protected override object CreateModel(
        ControllerContext controllerContext,
        ModelBindingContext bindingContext,
        Type modelType)
    {
        if (modelType.IsEntity() && FetchFromRepository)
        {
            var id = GetIdFromValueProvider(bindingContext.ValueProvider, modelType);
            if (id != 0)
            {
                var repository = repositoryResolver.GetRepository(modelType);
                object entity;
                try
                {
                    entity = repository.GetById(id);
                }
                finally
                {
                    repositoryResolver.Release(repository);
                }
                return entity;
            }
        }

        // Fall back to default model creation if the target is not an existing entity
        return base.CreateModel(controllerContext, bindingContext,
odelType);
    }

    private static int GetIdFromValueProvider(IValueProvider valueProvider, Type modelType)
    {
        var result = valueProvider.GetValue(modelType.GetPrimaryKey().Name);
        return (result == null) ? 0 : (int)result.ConvertTo(typeof(Int32));
    }

    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var model = base.BindModel(controllerContext, bindingContext);
        ValidateEntity(bindingContext, controllerContext, model);
        return model;
    }

    protected virtual void ValidateEntity(
        ModelBindingContext bindingContext,
        ControllerContext controllerContext,
        object entity)
    {
        // override to provide additional validation.
    }

    private bool FetchFromRepository
    {
        get
        {
            // by default we always fetch any model that implements IEntity
            return declaringAttribute == null ? true :
declaringAttribute.Fetch;
        }
    }

    public virtual void Accept(Attribute attribute)
    {
        declaringAttribute = (EntityBindAttribute)attribute;   
    }

    // For unit tests

    public void SetModelBinderDictionary(ModelBinderDictionary modelBinderDictionary)
    {
        Binders = modelBinderDictionary;
    }
}


We have simply inherited ASP.NET MVC’s DefaultModelBinder and overriden the CreateModel method. This allows us to check if the type being bound is one of our entities and then grabs its repository and gets it from the database if it is.

Now, We are most definitely not doing correct Domain Driven Development here despite our use of terms like ‘entity’ and ‘repository’. It’s generally frowned on to have table-row like settable properties and generic repositories. If you want to do DDD, you are much better off only binding view-models to your views