如何使用MVC3中的Ninject将服务注入view / viewmodel?

时间:2011-08-09 14:51:25

标签: .net asp.net-mvc-3 ninject service-locator

我正在使用MVC3和Ninject,我的控制器中的依赖关系没有问题。我有很少的服务,如本地化,格式提供程序,我希望它们被注入到视图模型或Razor视图中。现在我手动将它们注入我的View Models,

  1. 如何自动执行此操作?
  2. 我可以为Razor视图注入一些服务吗?
  3. 如何在MVC中使用Ninject设置服务定位器?
  4. 其他人: 似乎服务定位器是个坏主意,因为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();
        }
    }
    

2 个答案:

答案 0 :(得分:3)

如果您使用的是Ninject的MVC 3插件,那么创建所有可用的挂钩非常方便。我认为支持Razor视图:如果你创建一个扩展典型View类的类并将注入的依赖项添加到该类,我认为Ninject将能够注入这些项以便它们可用在视图中给你。

对于我的观点,我更倾向于使用基于HtmlHelper的自定义扩展方法,这些方法最终间接使用基于单一的Service Locator模式来访问相应的依赖项。如果您发现说Html.MyMethod(...)Url.MyMethod(...)或类似内容没有意义,那么您尝试包含的项目很可能不属于您的视图。

同样,Model对象通常应该只是POCO,与它们相关的逻辑量很少。用服务填充它们听起来像违反了MVC模型。正如Jason指出的那样,您可以从控制器的代码中设置模型上的格式提供程序。但是,我会说使用格式提供程序来生成您需要的字符串并将those放在模型上更好。

对Jason的帖子的评论的回应

方法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上。