Внедрение зависимостей в WPF с помощью Ninject - PullRequest
12 голосов
/ 20 июля 2009

У меня есть пользовательский элемент управления WPF, в который я хотел бы добавить зависимости. Какой лучший способ сделать это с Ninject ?

В качестве конкретного примера: у меня есть UserControl с именем MapView, и я хочу внедрить в него экземпляр моего IDialogueService с помощью конструктора или внедрения свойства. В настоящее время я не использую внедрение зависимостей, и мой элемент управления создан в XAML:

<Window x:Class="GameWindow" ...>
    <Grid Name="root">
        <MapView x:Name="mapView" ... />
        <!-- other stuff here -->
    </Grid>
</Window>

Создание IKernel и привязка IDialogueService достаточно просты. Но я застрял на том, как использовать ядро ​​для внедрения зависимостей в мой MapView. Я все еще новичок в Ninject, так что, может быть, есть что-то очевидное, чего мне не хватает.

Я могу придумать несколько способов решить эту проблему:

  1. Создание MapView в коде. Удалите <MapView ... /> из XAML и вместо этого добавьте это в конструктор GameWindow:

    public GameWindow(IKernel kernel) {
        root.Children.Add(kernel.Get<MapView>());
    }
    

    Недостатки: дополнительная сложность из-за неиспользования XAML; GameWindow зависит от IKernel.

  2. Сохраните экземпляр в XAML и используйте вместо него инъекцию свойства:

    public GameWindow(IKernel kernel) {
        kernel.Inject(mapView);
    }
    

    Недостаток: в документах Ninject говорится, что Inject () «не следует использовать в большинстве случаев», поэтому я даже не знаю, делает ли он то, что, как мне кажется, делает, или имеет ли смысл использовать его здесь. И GameWindow по-прежнему зависит от IKernel.

  3. Добавьте в GameWindow вводимые параметры / свойства, которые передают значения в MapView (возможно, через свойства в MapView), а затем используйте Get<GameWindow>(). Недостаток: теперь я вручную передаю зависимости повсеместно, и это то, что инфраструктура DI должна автоматизировать для меня.

  4. После создания экземпляра GameWindow, пройдите логическое дерево и вызовите IKernel.Inject () для всего. Недостатки: опять же, я не знаю, делает ли Inject () то, что я думаю, или это уместно здесь. Вызывающий должен помнить, что нужно выполнить процедуру «прогулка по визуальному дереву и инъекции» после создания экземпляра GameWindow.

Есть ли лучший способ сделать это? Может быть, расширение WPF для Ninject, которое позволяет мне делать Get<GameWindow>(), и автоматически просматривает логическое дерево для меня (как в # 4), делая внедрение свойств для всего? Если такой вещи не существует, могу ли я написать ее?

Как вы, ребята, подходите к использованию Ninject с WPF? Используете ли вы какой-либо из вышеперечисленных подходов (и если да, можете ли вы поделиться положительными или отрицательными сторонами, о которых я не знаю)? У тебя есть лучшие подходы?

1 Ответ

4 голосов
/ 20 июля 2009

1) лучше. Вы также найдете, что это удобная точка входа для функций Mapview.

Кроме того, вместо передачи в ядро, просто выполните kernel.Get () и [введите] MapView в GameWindow.

...