How to inject services into view/viewmodel using Ninject in MVC3?
I am using MVC3 with Ninject, Dependencies in my controller are resolved with no problem. I have few services like localization, format provider and I want them to be开发者_如何学Go injected into view models or Razor views. Right now I am manually injecting them to my View Models,
- How can I automate this?
- Can I inject some services to Razor views?
- How do I setup service locator using Ninject in MVC?
For others: It seems like Service Locator is bad idea because, Ninjects Bootstrapper.Kernel is obsolete and Service Locator is an anti pattern. Check out this article http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx
_
public class HomeController : Controller
{
//This gets injected correctly
[Inject]
public ILocalizationService LocalizationService { get; set; }
//This gets injected correctly
[Inject]
public MyModel Model { get; set; }
public ActionResult Index()
{
var modelResult = Model.GetStuff();
//Here I am manully injecting my services to my View Model,
//I would like Ninject to inject services into my view model.
var viewModelResult = IndexViewModel.Covert(LocalizationService, modelResult);
return View(viewModelResult);
}
public ActionResult About()
{
return View();
}
}
If you are using Ninject's MVC 3 plugin, it is pretty good about creating all the hooks that are available. I think there's support for Razor views: if you create a class that extends the typical View class and add injected dependencies to that class, I think Ninject will be able to inject those items so that they will be available to you in the View.
For my views, I've preferred to use custom HtmlHelper-based extension methods that end up indirectly using a singleton-based Service Locator pattern to access the appropriate dependencies. If you're finding that it doesn't make sense to say Html.MyMethod(...)
or Url.MyMethod(...)
or something like that, there's a strong probability that the item you're trying to include does not belong in your View.
Likewise, Model objects should generally just be POCOs, with a minimal amount of logic associated with them. Populating them with services sounds like a violation of the MVC model. As Jason points out, you could just set the format providers on the model from the controller's code. However, I'd say it's even better to use the format providers to generate the strings you're going to need and put those
on the model instead.
Response to comments on Jason's post
Approach 1 sounds like a good idea, as it sounds like your controller is getting complex and this is a good place to separate a concern into a different class. If you inject the Converter
itself into your controller rather than using it as a static class, then its dependencies will automatically be injected when Ninject is creating the controller.
public class HomeController : Controller
{
[Inject]
public ViewModelConverter Converter { get; set; }
[Inject]
public MyModel Model { get; set; }
public ActionResult Index()
{
var modelResult = Model.GetStuff();
var viewModelResult = Converter.MakeViewModel(modelResult);
return View(viewModelResult);
}
public ActionResult About()
{
return View();
}
}
public class ViewModelConverter
{
[Inject]
public ILocalizationService LocalizationService { get; set; }
public ViewModel MakeViewModel(MyModel model)
{
// You should be able to use LocalizationService here
}
}
I stuck with your property-based injection on this, even though I'd personally prefer using constructor injection.
Inject the format providers into the controller and then set them on the ViewModel when it is created.
精彩评论