Отличие ioc-контейнера от фабрики и сервис локатора

556 views
Skip to first unread message

Алексей Бложан

unread,
Nov 9, 2011, 10:30:09 AM11/9/11
to dotnetconf
В чем главное отличие этого патерна от фабрик и сервис локаторов? Я
понимаю, что оно в том, что ioc-контейнер получает имена файлов
сборок и использует рефлексию для разрешения зависимостей, благодаря
этому и происходит разрыв транзистивной зависимости от клиента
контейнера к этим сборкам. У фабрики и у сервис локатора клиент
транзистивно зависит от типов которые они используют.

Это так?

Ilya Dubadenko

unread,
Nov 9, 2011, 3:16:55 PM11/9/11
to dotne...@googlegroups.com
Как я понимаю,
фабрика каждый раз конструирует новый объект по запросу. Фабрика может выступать в роли creator'a для семейства классов, другими словами, на каждое семейство своя фабрика.

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

Рефлексия может использоваться как и в фабрике, так и в контейнере.
Обычно от фабрики не требуют сверх гибкости (как от контейнера) и поэтому чаще фабрика явно строит нужный нам объект, и явно делает для него Dependency Injection.

ServiceLocator, как я понимаю, создан для того чтобы избавить разработчика от нужды в Dependency Injection.


9 ноября 2011 г. 19:30 пользователь Алексей Бложан <aleksej...@gmail.com> написал:

Sergey Zwezdin

unread,
Nov 10, 2011, 9:34:45 AM11/10/11
to dotne...@googlegroups.com
IoC-контейнер - это частный случай фабрики.

Artur Drobinskiy

unread,
Nov 10, 2011, 10:20:11 AM11/10/11
to dotne...@googlegroups.com
ioc-контейнер - это "скрытое"/неявное использование сервис локатора.

Главное отличие как раз в "неявности" использования: объекты явно нигде не создаются. Вы объявляете конструктор, параметризованный сервисами-зависимостями и не беспокоитесь о том, как эти сервисы туда попадают.

Это главное отличие и даёт гибкость проекту с ioc - определить, какие реализации сервисов будут использоваться можно в одной точке - при старте/конфигурации приложения, в юнит-тестах реализации также очень легко подменить.


10 ноября 2011 г. 21:34 пользователь Sergey Zwezdin <ser...@zwezdin.com> написал:

Alexander Sidorov

unread,
Nov 10, 2011, 10:57:27 AM11/10/11
to dotne...@googlegroups.com
Согласен с Артуром, но добавлю эту ссылку: http://wiki.agiledev.ru/doku.php?id=ooad:dependency_injection В свое время именно эта статья разложила у меня в голове все по полочкам.

И небольшое уточнение. Неявность использования происходит только при пассивной инъекции, при активной инъекции IoC-контейнер используется явно, но активная инъекция это чуть ли не антипаттерн.

10 ноября 2011 г. 22:20 пользователь Artur Drobinskiy <artur.dr...@gmail.com> написал:

Alexander Byndyu

unread,
Nov 10, 2011, 10:51:52 PM11/10/11
to dotne...@googlegroups.com
Всем привет!

Как-то быстро тема перешла от ServiceLocator к IoC-контейнеру. Я бы хотел остановиться на поставленном вопросе: В чем отличие ServiceLocator от Factory?

Точные определения можно найти в книжках и википедиях. Здесь я хочу изложить основные моменты.

1. ServiceLocator - объект, который хранит в себе соответствие между интерфейсами с их реализациями. SL может регистрировать новые интерфейсы. По запросу к SL может по интерфейсу создать сохраненную в нем реализацию. SL нужен для пассивного внесения зависимостей.

Классическая реализация ServiceLocator:
  1. public static class ServiceLocator
  2. {
  3.         private static readonly Dictionary<Type, Type> services = new Dictionary<Type, Type>();
  4.  
  5.         public static void RegisterService<t>(Type service)
  6.         {
  7.                 services[typeof (T)] = service;
  8.         }
  9.  
  10.         public static T Resolve<T>()
  11.         {
  12.                 return (T) Activator.CreateInstance(services[typeof (T)]);
  13.         }
  14. }
Например, в SL можно добавить соответствие между интерфейсом IMailService и классом EmailService, который реализует этот интерфейс. Использование ServiceLocator будет выглядеть так:


   1:  public class SomeClass 

   2:  {

   3:      private readonly IMailSender mailSender;
   5:   
   6:      public SomeClass() : this(ServiceLocator.Resolve<IMailSender>())
   7:      {
   8:      }

   9:   

  10:      public SomeClass(IMailSender mailSender)

  11:      {

  12:          this.mailSender = mailSender;

В данном случае SL используется, чтобы скрыть реализацию класса IMailSender для его безболезненной подмены на другую реализацию.

2. Factory - объект, который умеет создавать класс или определенную группу классов. Внутри фабрики может происходить конфигурация создаваемых объектов. Фабрика может использовать ServiceLocatory или IoC-контейнер для создания объектов. 

Например, объект QueryFactory отсюда http://blog.byndyu.ru/2011/08/repository.html.

С помощью IoC-контейра можно сделать полностью бестелесную фабрику только с интерфейсом, например, http://blog.byndyu.ru/2011/08/queryfactory-iqueryfactory.html

В дополнение хотел бы привести ссылки:

--
Best regards,
Byndyu Alexander
Technical Director at IndyCode – www.indycode.ru

Phone: +7 (904) 305 5263
Skype: alexander.byndyu
Blog: http://blog.byndyu.ru
Twitter: alexanderbyndyu



10 ноября 2011 г. 21:57 пользователь Alexander Sidorov <alex...@gmail.com> написал:

Алексей Бложан

unread,
Nov 11, 2011, 12:34:38 AM11/11/11
to dotnetconf
Ну я вот писал свой сервис локатор, который все объекты рекурсивно
создавал сам по сигнатурам интерфейсов. Это значит у меня был ioc-
контейнер?

Alexander I. Zaytsev

unread,
Nov 11, 2011, 12:40:36 AM11/11/11
to dotne...@googlegroups.com


11 ноября 2011 г. 11:34 пользователь Алексей Бложан <aleksej...@gmail.com> написал:

Ну я вот писал свой сервис локатор, который все  объекты рекурсивно
создавал сам по сигнатурам интерфейсов. Это значит у меня был ioc-
контейнер?
Да

Алексей Бложан

unread,
Nov 11, 2011, 12:42:21 AM11/11/11
to dotnetconf
Спасибо! Теперь понятно.

On 11 ноя, 09:40, "Alexander I. Zaytsev" <hazzik+nos...@gmail.com>
wrote:


> 11 ноября 2011 г. 11:34 пользователь Алексей Бложан <

> aleksej.bloz...@gmail.com> написал:

Reply all
Reply to author
Forward
0 new messages