У меня есть пользовательский элемент управления 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, так что, может быть, есть что-то очевидное, чего мне не хватает.
Я могу придумать несколько способов решить эту проблему:
Создание MapView в коде. Удалите <MapView ... />
из XAML и вместо этого добавьте это в конструктор GameWindow:
public GameWindow(IKernel kernel) {
root.Children.Add(kernel.Get<MapView>());
}
Недостатки: дополнительная сложность из-за неиспользования XAML; GameWindow зависит от IKernel.
Сохраните экземпляр в XAML и используйте вместо него инъекцию свойства:
public GameWindow(IKernel kernel) {
kernel.Inject(mapView);
}
Недостаток: в документах Ninject говорится, что Inject () «не следует использовать в большинстве случаев», поэтому я даже не знаю, делает ли он то, что, как мне кажется, делает, или имеет ли смысл использовать его здесь. И GameWindow по-прежнему зависит от IKernel.
Добавьте в GameWindow вводимые параметры / свойства, которые передают значения в MapView (возможно, через свойства в MapView), а затем используйте Get<GameWindow>()
. Недостаток: теперь я вручную передаю зависимости повсеместно, и это то, что инфраструктура DI должна автоматизировать для меня.
После создания экземпляра GameWindow, пройдите логическое дерево и вызовите IKernel.Inject () для всего. Недостатки: опять же, я не знаю, делает ли Inject () то, что я думаю, или это уместно здесь. Вызывающий должен помнить, что нужно выполнить процедуру «прогулка по визуальному дереву и инъекции» после создания экземпляра GameWindow.
Есть ли лучший способ сделать это? Может быть, расширение WPF для Ninject, которое позволяет мне делать Get<GameWindow>()
, и автоматически просматривает логическое дерево для меня (как в # 4), делая внедрение свойств для всего? Если такой вещи не существует, могу ли я написать ее?
Как вы, ребята, подходите к использованию Ninject с WPF? Используете ли вы какой-либо из вышеперечисленных подходов (и если да, можете ли вы поделиться положительными или отрицательными сторонами, о которых я не знаю)? У тебя есть лучшие подходы?