3

我将 MVC3 与 Ninject 一起使用,我的控制器中的依赖关系已毫无问题地解决。我几乎没有像本地化、格式提供程序这样的服务,我希望将它们注入到视图模型或 Razor 视图中。现在我手动将它们注入到我的视图模型中,

  1. 我怎样才能自动化呢?
  2. 我可以向 Razor 视图注入一些服务吗?
  3. 如何在 MVC 中使用 Ninject 设置服务定位器?

对于其他人: 似乎 Service Locator 是个坏主意,因为 Ninjects Bootstrapper.Kernel 已过时,而 Service Locator 是一种反模式。看看这篇文章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();
    }
}
4

2 回答 2

3

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

就我的观点而言,我更喜欢使用自定义的基于 HtmlHelper 的扩展方法,最终间接使用基于单例的服务定位器模式来访问适当的依赖项。Html.MyMethod(...)如果您发现说或或类似的话没有意义Url.MyMethod(...),那么您尝试包含的项目很可能不属于您的视图。

同样,模型对象通常应该只是 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
    }
}

我坚持使用基于属性的注入,即使我个人更喜欢使用构造函数注入。

于 2011-08-09T15:02:44.557 回答
1

将格式提供程序注入控制器,然后在创建时将它们设置在 ViewModel 上。

于 2011-08-09T14:55:07.773 回答