Как и было обещано в одном из моих предыдущих постов, я потрачу некоторое время на объяснение различий между различными методами инверсии управления (IoC), поддерживаемыми Silverlight для Windows Phone. Этот пост о Ninject. Я также попытаюсь сравнить несколько реализаций IoC в одной из моих будущих статей.
Прежде чем приступить к обучению, я упомяну несколько фактов, касающихся Ninject в целом.
- Ninject является известным инжектором зависимостей .NET
- Вы можете скачать Ninject с их сайта
- Вы можете расширить функции Ninject с помощью расширений.
- Ninject также поддерживается Silverlight и Windows Phone 7
- Ninject поддерживает конструктор, свойства и внедрение метода
- Ninject поддерживает 4 области инъекций: Scope, Singleton, Thread, Transient
Но давайте не будем тратить много времени на факты и перейдем непосредственно к нашему руководству по Windows Phone.
Настроить
Загрузите Ninject для Windows Phone со следующего веб-сайта . Создайте новый проект Windows Phone по умолчанию в Visual Studio и добавьте туда ссылки Ninject для Windows Phone (DLL).
Создание простых провайдеров данных
Предположим, что наш продукт имеет как тестовую, так и производственную среду. Каждый из них имеет свою собственную реализацию, унаследованную от одного интерфейса: ITextDataProvider.
public interface ITextDataProvider
{
string GetText();
}
И реализации:
public class ProductionDataProvider : ITextDataProvider
{
public string GetText()
{
return "production text";
}
}
public class TestTextDataProvider : ITextDataProvider
{
public string GetText()
{
return "test text";
}
}
Создание контейнера IoC
Контейнер также довольно прост. Он состоит из экземпляра класса StandardKernel, метода Initialize и универсального метода Get, который возвращает экземпляр с внедренными элементами на основе параметра Type. Метод Initialize просто связывает различные реализации в зависимости от текущего действия Build проекта (Debug, Release) с типом ITextDataProvider.
public static class IoCContainter
{
private static readonly IKernel Kernel = new StandardKernel();
public static void Initialize()
{
#if DEBUG
Kernel.Bind<ITextDataProvider>().To<TestTextDataProvider>();
#else
Kernel.Bind<ITextDataProvider>().To<ProductionDataProvider>();
#endif
}
public static T Get<T>()
{
return Kernel.Get<T>();
}
}
Инициализация контейнера IoC
Теперь нам нужно инициализировать контейнер IoC где-нибудь, и, вероятно, наиболее подходящим местом для этого были бы события App.xaml.cs: Application_Launching и Application_Activation, которые запускаются при каждом запуске приложения.
// Code to execute when the application is launching (eg, from Start)
// This code will not execute when the application is reactivated
private void Application_Launching(object sender, LaunchingEventArgs e)
{
IoCContainter.Initialize();
}
// Code to execute when the application is activated (brought to foreground)
// This code will not execute when the application is first launched
private void Application_Activated(object sender, ActivatedEventArgs e)
{
IoCContainter.Initialize();
}
Создание ViewModel
Надеюсь, вы уже познакомились с шаблоном Model-View-ViewModel (MVVM) , который довольно популярен в мире Silverlight. Если нет, то в интернете достаточно информации. Для ViewModel необходимо добавить свойство типа ITextDataProvider и добавить в него атрибут [Inject]. Это свойство будет введено внутри ядра. Также вам нужно ввести очень простое свойство, которое возвращает текст для отображения в пользовательском интерфейсе.
public class NinjectSampleViewModel
{
[Inject]
public ITextDataProvider TextDataProvider { get; set; }
public string TextToDisplay
{
get { return TextDataProvider.GetText(); }
}
}
Создание представления
Последний шаг — создать представление (или страницу) для отображения результатов. Для этого я создал страницу XAML для Windows Phone по умолчанию и немного изменил элемент ContentPanel, добавив TextBlock со свойством Text Binding внутри.
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<TextBlock x:Name="tbText" Text="{Binding TextToDisplay}" />
</Grid>
Что касается кода, я также немного его изменил, присвоив свойство DataContext с помощью нашей ViewModel, используя класс IoCContainer.
public NinjectSampleView()
{
InitializeComponent();
DataContext = IoCContainter.Get<NinjectSampleViewModel>();
}
Полученные результаты
После запуска приложения вы увидите «рабочий текст» или «тестовый текст», отображаемый в зависимости от вашего действия по сборке.
Вы можете найти исходный код внутри проекта EugeneDotnetIoCSamples внутри проекта GitHub EugeneDotnetWPCodeSamples: