Yvision.kz
kk
Разное
Разное
399 773 постов42 подписчика
Всяко-разно
-9
04:09, 24 октября 2014

Инверсия управления (TinyIoC)

Как известно, инверсия управления, это важный принцип SOLID, позволяющий писать слабо связанный код, повышая в разы гибкость кода.

Существует множество IoC-контейнеров (NInject, Unity, AutoFac и другие).

Для начинающих есть хорошая статья здесь.

Я же, в своих проектах использую TinyIoC - небольшие размеры, и то, что его использует проект NancyFx (Уроки по фреймворку nancy, и объяснение, что это, можно найти тут).

Первая задача - нам нужно объявить контейнер и что-то в него положить.

Проект у меня простой и демонстрационный, поэтому статического контейнера мне вполне хватает.

 
  1. public static class AppContainer
  2. {
  3. private static TinyIoCContainer _instance;
  4. public static TinyIoCContainer Instance
  5. {
  6. get { return _instance ?? RegisterInstance(); }
  7. }
  8. private static TinyIoCContainer RegisterInstance()
  9. {
  10. var instance = new TinyIoCContainer();
  11. instance.Register<IYviEnumerable, YviEnumerable>();
  12. _instance = instance;
  13. return _instance;
  14. }
  15. }

В этом коде я в контейнере регистрирую некоторый интерфейс и реализацию, которая может поменяться в любой момент (достаточно написать класс, отнаследовавшись от IYviEnumerable и заменить ненужный нам класс).

Использование контейнера.

Типы, зарегистрированные в контейнере можно запросить напрямую из контейнера:

 
  1. var yviEnumerable = AppContainer.Instance.Resolve<IYviEnumerable>();

Либо инъекцией типа в конструктор любого класса.

На этом пока всё.

Небольшая поправка.

Что делать, если нам требуется зарегистрировать в контейнере несколько классов одного и того же интерфейса?

   
  1. instance.Register<IModule, StatisticLoader>("statistic");
  2. instance.Register<IModule, Storage>("storage");
  3. instance.Register<IModule, Http>("http");

Просто регистрируем:)

И резольвим список классов, зарегистрированных на один и тот же интерфейс:

   
  1. IEnumerable<IModule> modules = container.ResolveAll<IModule>();
-9
675
0