我正在使用MVC3和Ninject,我的控制器中的依赖关系没有问题。我有很少的服务,如本地化,格式提供程序,我希望它们被注入到视图模型或Razor视图中。现在我手动将它们注入我的View Models,
其他人: 似乎服务定位器是个坏主意,因为Ninjects Bootstrapper.Kernel已经过时,而服务定位器是一种反模式。查看此文章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();
}
}
答案 0 :(得分:3)
如果您使用的是Ninject的MVC 3插件,那么创建所有可用的挂钩非常方便。我认为支持Razor视图:如果你创建一个扩展典型View类的类并将注入的依赖项添加到该类,我认为Ninject将能够注入这些项以便它们可用在视图中给你。
对于我的观点,我更倾向于使用基于HtmlHelper的自定义扩展方法,这些方法最终间接使用基于单一的Service Locator模式来访问相应的依赖项。如果您发现说Html.MyMethod(...)
或Url.MyMethod(...)
或类似内容没有意义,那么您尝试包含的项目很可能不属于您的视图。
同样,Model对象通常应该只是POCO,与它们相关的逻辑量很少。用服务填充它们听起来像违反了MVC模型。正如Jason指出的那样,您可以从控制器的代码中设置模型上的格式提供程序。但是,我会说使用格式提供程序来生成您需要的字符串并将those
放在模型上更好。
方法1听起来像个好主意,因为听起来你的控制器变得越来越复杂,这是将关注点分成不同类的好地方。如果将Converter
本身注入控制器而不是将其用作静态类,则在Ninject创建控制器时将自动注入其依赖项。
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
}
}
我坚持使用基于属性的注射,即使我个人更喜欢使用构造函数注入。
答案 1 :(得分:1)
将格式提供程序注入控制器,然后在创建时将它们设置在ViewModel上。