Как внедрить сервисы в view / viewmodel, используя Ninject в MVC3? - PullRequest
3 голосов
/ 09 августа 2011

Я использую MVC3 с Ninject, зависимости в моем контроллере решаются без проблем.У меня есть несколько служб, таких как локализация, поставщик форматов, и я хочу, чтобы они были внедрены в модели представлений или представления Razor.Прямо сейчас я вручную внедряю их в свои модели просмотра,

  1. Как я могу автоматизировать это?
  2. Можно ли внедрить некоторые службы в представления Razor?
  3. Как настроить поиск служб с помощью Ninject в MVC?

Для других: Похоже, 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();
    }
}

Ответы [ 2 ]

3 голосов
/ 09 августа 2011

Если вы используете плагин Ninject для MVC 3, то неплохо создать все доступные хуки.Я думаю есть поддержка представлений Razor: если вы создадите класс, который расширяет типичный класс View и добавит в него вставленные зависимости, я думаю, что Ninject сможет внедрить эти элементы, чтобы они были доступны длявы в представлении.

Для моих представлений я предпочел использовать настраиваемые методы расширения на основе HtmlHelper, которые в конечном итоге косвенно используют шаблон Service Locator на основе одноэлементного доступа для доступа к соответствующим зависимостям.Если вы обнаружите, что нет смысла говорить Html.MyMethod(...) или Url.MyMethod(...) или что-то в этом роде, есть большая вероятность, что элемент, который вы пытаетесь включить, не принадлежит вашему представлению.

Аналогично, объекты модели, как правило, должны быть просто POCO с минимальным количеством логики, связанной с ними.Заполнение их сервисами звучит как нарушение модели MVC.Как отмечает Джейсон, вы можете просто установить поставщиков формата для модели из кода контроллера.Тем не менее, я бы сказал, что еще лучше использовать провайдеры форматирования для генерации строк, которые вам понадобятся, и вместо этого поставить модель 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 голос
/ 09 августа 2011

Вставьте поставщики форматов в контроллер, а затем установите их в ViewModel при его создании.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...