[1] .
Там нет ничего встроенного, и многие люди создали свои собственные решения. Включая, но не ограничиваясь:
Funq ,
MicroIoc ,
TinyIoc ,
это или
это . Но никто из них не работает так, как я хочу.
Я хочу:
- Автоматическое введение параметров конструктора
- Явное указание того, где существует зависимость
- Явная конфигурация того, как должны быть разрешены зависимости
- Свободная конфигурация
Я не хочу
- Параметр впрыска
- Автоматическое разрешение зависимостей
- Aribtrary ServiceLocator
Меня не волнует
- Позволяя контейнеру управлять синглетонами
- Вложенное / связанное разрешение зависимостей
На мои требования влияют два фактора:
1. Мой предыдущий опыт работы с
Castle Windsor — выбран после оценки того, что было доступно в то время (около 4 лет назад).
2. Мой опыт работы в командах разработчиков, где всегда будет по крайней мере, один человек, который не был заинтересован в изучении чего-либо нового, лучших практик или, по-видимому, качества кода. Я узнал, что если вы работаете с такими людьми или с кем-то новым в отрасли, вы сэкономите себе много времени (исправляя их ошибки и повторяя им объяснения), если все будет ясно и ясно, а не «волшебно», потому что, если они не могут понять это, они не могут обновить или исправить это, если есть проблема.
Итак, я написал что-то сам:
http://github.com/mrlacey/NanoIoC
Как отмечено в комментариях, это не обеспечивает автоматическое внедрение конструктора. К сожалению, платформа просто не поддерживает способ сделать это. Это моя следующая лучшая вещь. — Надеюсь, это прояснит ситуацию.
Да, название — это ссылка на MicroIoc & TinyIoC, но намекает, что у меня
гораздо меньше кода. (Это меньше 90 LOC.)
Да, я знаю, что это скорее структура DI, чем IOC, но в реальном мире термины используются довольно взаимозаменяемо, поэтому я доволен этим.
Как это использовать:
Для класса, который имеет некоторые внешние зависимости, мы объявляем это, помечая их интерфейсом «ISupportInjectionOf <T>». В качестве примера, если бы мы хотели указать, что страница имеет зависимость до «IRepository» и «IDateTimeHelper», мы бы сделали это:
public partial class MainPage : PhoneApplicationPage, ISupportInjectionOf<IRepository>, ISupportInjectionOf<IDateTimeHelper> {
Затем в нашем конструкторе мы разрешим эти зависимости:
private IRepository repository; private IDateTimeHelper dateTime; public MainPage() { InitializeComponent(); repository = this.GetDependency<IRepository>(); dateTime = this.GetDependency<IDateTimeHelper>(); }
Да, мы можем разрешить зависимости в любое время, но в моем коде это всегда будет в конструкторах.
Это важно для поддержания тестируемости и ремонтопригодности. (Я устанавливаю соглашение.)
В приведенном выше примере я бы также включил перегрузку конструктора для непосредственного внедрения зависимостей во время тестирования:
#if TEST public MainPage(IRepository repo, IDateTimeHelper dateTimeHelper) { InitializeComponent(); this.repository = repo; this.dateTime = dateTimeHelper; } #endif
Просто!
Конфигурация:
Конфигурация проста и выполняется на уровне приложения. Мы можем объявить, как каждая зависимость должна решаться отдельно:
NanoIocConfig.RegisterDependency<IRepository>(new ViewModelRepository()); NanoIocConfig.RegisterDependency<IDateTimeHelper>(new DateTimeHelper());
Или через свободный интерфейс:
NanoIocConfig.RegisterDependency<IRepository>(new ViewModelRepository()) .And<IDateTimeHelper>(new DateTimeHelper());
Очевидно, что все эти примеры используют интерфейсы. Но мы не должны. Предполагая, что мы не хотим скрывать «DateTimeHelper» за интерфейсом, мы можем просто сделать это (обратите внимание, что тип выводится):
NanoIocConfig.RegisterDependency(new DateTimeHelper()); dth = this.GetDependency<DateTimeHelper>();
Все приведенные выше примеры создают экземпляр для использования каждый раз, когда зависимость разрешается.
Вместо этого мы могли бы передать экземпляр синглтона традиционным способом:
NanoIocConfig.RegisterDependency<IRepository>(ViewModelRepository.Instance);
Если вам нужны разные экземпляры каждый раз, когда зависимость разрешается, просто передайте фабрику и получите новые экземпляры таким образом.
Что вы думаете?
Полезно?
Интересный?
Что-то, что вы можете использовать?
Хотите, чтобы он был включен в пакет NuGet? (Либо в виде библиотеки, либо в виде одного исходного файла).
Мне бы очень хотелось узнать, что вы думаете.
[1] Было бы замечательно, если бы в (предпочтительно близкой) будущей версии Windows Phone SDK он включал инструменты, которые позволят упростить реализацию хороших методов разработки в нашем коде Windows Phone. Удивительно, что они упростили людям начало разработки для платформы, но эти новички должны со временем знать, как написать лучший код, и если инструменты их остановят, у них нет стимула учиться. А для тех из нас, кто считает себя профессионалами и зарабатывает на жизнь, мы хотим иметь возможность применять лучшие практики к нашему коду (работе), а не иметь SDK и инструментарий, мешающих нам делать основные вещи.