Simon
Simon

Reputation: 592

How do I inject request-specific details into models

First some background.

I'm trying to provide a model API to my colleagues that looks a bit like this.

public class ProductFilterViewModel : ModelBase
{
    [SelectItem ManagerType = typeof(UnitManager)
                SelectMethod = "GetUnits"
                TextProperty = "Name"
                ValueProperty = "Text"]
    IEnumerable<SelectListItem> UnitSelectItems { get; set; }

    public IModelContext ModelContext { get; set; }

    // More properties etc.
}


public interface IModelContext
{
    string AccessToken { get; }
}

Users of my API should either be able to create a new instance (via a Factory method, or using an NInject container, either is fine) or have instances of this bound to a controller parameter and have the following happen - the properties attributed with [SelectItem] should be populated and an instance of IModelContext should be injected.

public class SomeController : Controller
{
    public ActionResult Index()
    {
        // or whatever
        ProductFilterViewModel model = this.Container.Get<ProductFilterViewModel>();
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(ProductFilterViewModel model)
    {
        model.RunSearch(); // will internally use model.ModelContext.AccessToken;
        return View(model);
    }
}

Now, the AccessToken property comes from a cookie and is essential for any database access that occurs within the model - including the automatic population of those properties attributed with [SelectItem]

I can get this working with model binding perfectly. Where I'm struggling is how to get this going in the non-binding case without duplicating code. Ideally the model binder would use the same factory / container. I've tried setting things up via DependencyResolver.Current but then I struggled with how to configure the container to inject that AccessToken from the cookie at request time. The only other idea I had was to configure the container in a ControllerBase class and then access it from the ControllerContext in my model binder, but that seems icky.

Upvotes: 0

Views: 89

Answers (1)

Remo Gloor
Remo Gloor

Reputation: 32725

I think you are heading the wrong direction. View Models shouldn't be created using an IoC container. They should be dumb data containers without any dependencies.

Instead provide some services that can be injected to the controllers that will to the work currently provided by your view models and have to controller assign them properly to the view model. You can prevent various ugly things this way and your problem can be solved very easily.

Upvotes: 2

Related Questions