1

Мне очень нравится концепция DI. Но для меня смысл DI всегда заключался в том, что все зависимости внедряются через конструктор основываясь на указанном интерфейсе:

__constructor(OneInterface $one, TwoInterface $two)

В DIC я указываю реализацию интерфейсов OneInterface и TwoInterface, и он сам подставляет все на свои места (autowiring?)


А вот SL, что-то типо ассоциативного массива, в котором есть разные сервисы под своими уникальными именами.

$service = $sl->get('someService');

Все было хорошо, пока не решил почитать документацию к Symfony, где в через DIC можно сделать вот такой хитрый финт:

$container->get('app.some.service');

И тут я почувствовал запах SL. Я слышал, как ругают ServiceLocator. Практика показала, что его есть за что ругать.

Но чем тогда DIC принципиально отличается от SL, если и там и там можно по имени обратиться к сервису? По сути, DIC это очень навороченный SL? Или я что-то где-то упустил?

  • 2
    Ну разницу между DI и SL вы понимаете - при DI все классы требуют явных зависимостей, а при SL могут принять контейнер из которого "сами все вытащат", чем делают зависимости неявными. А разница между get в месте их использования. В случае SL это везде, а в случае DIC только на самом верхнем уровне (нужно же где то инстанцировать графы зависимостей) или исключительные случаи – vitidev Jan 15 '18 at 21:15
  • В тему https://ru.stackoverflow.com/questions/461814/%d0%97%d0%b0%d1%87%d0%b5%d0%bc-%d0%bd%d1%83%d0%b6%d0%b5%d0%bd-dependency-injection-%d0%ba%d0%be%d0%bd%d1%82%d0%b5%d0%b9%d0%bd%d0%b5%d1%80?rq=1 – svgrafov Jan 16 '18 at 09:41

1 Answers1

1

Обычно у всевозможных IoC контейнеров есть подобный метод. Где-то он называется Resolvе, где-то get. В отличие от ServiceLocator он не просто предоставляет постоянно живущий объект по требованию. Он может каждый раз создавать новый объект или выдавать всегда один и тот же экземпляр. Это зависит от настроек контейнера.

Этот метод не стоит использовать в коде обычных классов. Это нарушает SRP. Обычно он используется в фабриках, провайдерах объектов и т.п.

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