Ответ 1
Как я уже сказал в своем комментарии к вашему OP, вся необходимая информация доступна в документации Ninject. Тем не менее, можно утверждать, что легко потеряться в своей обширной документации, если вы не знакомы с Ninject и/или DI.
Есть несколько обучающих онлайн, из которых этот, который я считал особенно информативным. Пока он дает пример с помощью console application
, принципы работы Ninject
остаются неизменными.
Независимо от типа вашего приложения вы настраиваете свой контейнер в точке входа приложения;
- Консольное приложение -
Main
- WPF -
App
(если вы не используете фреймворк, в этом случае вы можете предоставить настраиваемый загрузчик) - ASP.NET - не знаю, возможно, кто-то может просветить меня.
ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ Я не утверждаю, что являюсь авторитетом на Ninject
или DI
, ниже - просто быстрый пример того, как я понимаю, что эти два объекта могут использоваться в сочетании друг с другом.
Например, ради, давайте работать с примерами, представленными в документации Ninject.
1) Создайте приложение WPF с именем NinjectIoC
2) Используйте Nuget для добавления ссылки на проект Ninject
3) Откройте App.xaml
и удалите свойство StartupUri
из элемента Application
, чтобы ваш App.xaml
выглядел следующим образом:
<Application x:Class="NinjectIoC.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
</Application.Resources>
</Application>
Причина, по которой мы это делаем, заключается в том, что свойство StartupUri
сообщает приложению WPF
, какой элемент управления пользовательским интерфейсом первоначально отображается при запуске приложения. Мы будем использовать Ninject
для отображения нашего начального элемента управления пользовательского интерфейса.
4) Откройте App.xaml.cs
. Здесь мы будем настраивать Ninject
container
или Kernel
для использования терминологии Ninject
. Мы override
метод OnStartup
приложения, чтобы мы могли сконфигурировать наш container
и впоследствии инициализировать приложение так, как хотелось бы. Обновите содержимое своего App.xaml.cs
, чтобы выглядеть следующим образом:
namespace NinjectIoC
{
using Ninject;
using System.Windows;
public partial class App
{
private IKernel container;
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
ConfigureContainer();
ComposeObjects();
Current.MainWindow.Show();
}
private void ConfigureContainer()
{
this.container = new StandardKernel();
container.Bind<IWeapon>().To<Sword>().InTransientScope();
}
private void ComposeObjects()
{
Current.MainWindow = this.container.Get<MainWindow>();
Current.MainWindow.Title = "DI with Ninject";
}
}
}
Краткое объяснение:
4.1) OnStartup - Override the
OnStartup method so that we may configure our
container` и инициализировать приложение по своему желанию.
4.2) ConfigureContainer
- Сообщите нашему container
, как мы хотели бы разрешить наши конкретные типы. Это гораздо больше, чем я показал в этом примере, однако, это гораздо больше, чем я показал. Существуют такие темы, как Multi Binding, Соглашения о привязке и Модули ядра, о которых вы лучше всего узнаете из официальной документации .
4.3) ComposeObjects
- Удалив свойство StartupUri
из App.xaml
, мы должны сообщить приложению, какой элемент управления UI мы хотели бы использовать для MainWindow
. Наряду с тем, чтобы наш container
использовал MainWindow
в качестве нашего MainWindow
, мы также устанавливаем свойство Title
. Снова вы можете сделать другие задачи здесь для ручной компоновки объектов.
Вам не нужно выделять шаги, как я уже выше, для этого надуманного примера было бы более бессмысленно не беспокоиться. По мере того, как ваше приложение растет, и вы начинаете делать более сложные вещи с помощью container
, разделение некоторых этапов начинается с того, что конфигурация container
более управляема. Выбор за вами.
5) Далее откройте MainWindow.xaml
, затем скопируйте и вставьте следующее:
<Window x:Class="NinjectIoC.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="78" Width="362">
<Grid>
<Button Content="Button" HorizontalAlignment="Left" Margin="269,10,0,0" VerticalAlignment="Top" Width="75" Click="Attack"/>
<TextBox x:Name="Target" HorizontalAlignment="Left" Height="23" Margin="10,10,0,0" VerticalAlignment="Top" Width="254"/>
</Grid>
</Window>
Я не буду объяснять это выше, поскольку должно быть очевидно, что происходит.
6) Наконец откройте MainWindow.xaml.cs
и обновите его следующим образом:
namespace NinjectIoC
{
using System.Windows;
public partial class MainWindow
{
private readonly IWeapon weapon;
public MainWindow(IWeapon weapon)
{
this.weapon = weapon;
InitializeComponent();
}
private void Attack(object sender, RoutedEventArgs e)
{
this.weapon.Hit(this.Target.Text);
}
}
public class Sword : IWeapon
{
public void Hit(string target)
{
MessageBox.Show(@"I swing and thrust my sword about like a mad man at " + target);
}
}
public interface IWeapon
{
void Hit(string target);
}
}
Снова я сделаю это краткое изложение, поскольку то, что происходит выше, не имеет ничего общего с конфигурацией Ninject
, и оно должно снова быть очевидным, что происходит.
Главное, что следует заметить в приведенном выше, - это argument
, который ожидает конструктор MainWindow
; IWeapon
. Вы можете спросить себя, как это решить, поскольку я не создаю конкретную реализацию Weapon
где угодно?
Хорошо во время ConfigureContainer
метода в App.xaml.cs
мы сообщили container
, как мы хотим, чтобы он разрешал зависимости для IWeapon
:
container.Bind<IWeapon>().To<Sword>().InTransientScope();
Приведенное выше указывает container
, что везде, где он встречает зависимость для IWeapon
, мы хотели бы предоставить экземпляр Weapon
. После запроса container
решения (Get
) нашего начального элемента управления MainWindow
, используя следующее:
Current.MainWindow = this.container.Get<MainWindow>();
container
рассмотрел его конструкторы и определил конструктор с большинством аргументов, которые он понял. В этом примере конструктор потребовал реализации IWeapon
и oh look, container
знает, как разрешить эту зависимость, потому что мы рассказали ей, как это сделать раньше в ConfigureContainer
.
Предполагая, что ни вы, ни я не допустили ошибок с указанным выше кодом, нажатие F5
должно запустить приложение, и вы увидите небольшое окно с TextBox
и Button
. Введите что-то в TextBox
, затем нажмите Button
, и вы увидите элемент управления MessageBox
, информирующий вас о том, что вы взмахнули своим мечом как "mad man"
тем, кто или что вы ввели в TextBox
.
Существует гораздо больше для Ninject
и DI
, чем я описал здесь. Например, есть целые книги по теме DI
, такие как этот Марк Сееман.
Надеемся, что вышеизложенное даст вам основную отправную точку, где искать и куда идти дальше, с вашими приключениями с помощью Ninject
и DI
.