Интерфейс DI, нужно авторитетное мнение

  • Автор темы Автор темы t43
  • Дата начала Дата начала
Так у тебя в bindFor просто имя сервиса будет другое, нет?
bindFor используется что бы указать специальную связь (какой именно сервис передать), для определённого сервиса.

$di->getConfigurator()->getConfig('ICache')->bind('FileCache')->bindFor('b','MemCached');
по русски:
Для интерфейса ICache по умолчанию использовать класс FileCache(сервис), для сервиса b(есть зависимость ICache), использовать MemCached.
 
ну я не просто так ссылку дал, там при похожем внешнем api код намного элегантнее (хоть и 8-летней давности)
 
ну я не просто так ссылку дал, там при похожем внешнем api код намного элегантнее (хоть и 8-летней давности)
Ну если не сложно, покажите где я реально туплю (не элегантно), со стороны это будет лучше видно.
Я серьёзно, без иронии.
 
я дал пример, где то же самое написано красиво и элегантно.

в то, что делает портянка типа как у тебя getService без юнит тестов я вникать не хочу, извини
 
я дал пример, где то же самое написано красиво и элегантно.

в то, что делает портянка типа как у тебя getService без юнит тестов я вникать не хочу, извини
Вы походу про тот кусок что в посте сейчас пишите, я переписал это давно, ну да ладно.

https://github.com/BobrD/DependencyInjection
 
При наличии юнит тестов все было бы понятно за одну минуту, а тут надо вникать. Вникать мне лень, потому просто дал пример, где точно знаю, что та же задача решена очень неплохо.
 
bindFor используется что бы указать специальную связь (какой именно сервис передать), для определённого сервиса
Ну это понятно. Но ты так говоришь, словно сервис == класс. Это неправильно. Не нужно
PHP:
$di->get('a',['*cache'=>'MemCached '])
$di->get('a',['*cache'=>'FileCache'])
Нужно
PHP:
$di->get('a1')
$di->get('a2')
 
Ну это понятно. Но ты так говоришь, словно сервис == класс. Это неправильно. Не нужно
PHP:
//Получить сервис а испольльзовать MemCached как ICache
$di->get('a',['*cache'=>'MemCached '])
//Тут опять получить сервис а но с FileCache
$di->get('a',['*cache'=>'FileCache'])
Нужно
PHP:
//Получить сервис а1
$di->get('a1')
//Получить сервис а2
$di->get('a2')
a1 !== a2
Ой, что то я вас не понимаю)
завтра с утра ещё раз перечитаю и попробую въехать.
 
Последнее редактирование:
Не понимаешь, потому что ты считаешь, что a1 и a2 — это имена классов. А это имена сервисов. Сервис — это не класс, это объект.

В общем, ни у тебя, ни у phemto нельзя получить сервис одного и того же класса с разными зависимостями, что является серьёзным минусом.

Писать
PHP:
$di->get('a',['*cache'=>'MemCached '])
не выход, потому что ты выносишь часть конфига в код и нарушаешь инкапсуляцию. Более того, в таком случае ты будешь вынужден передавать инстанс контейнера внутрь, чтобы уже там нарушить инкапсуляцию для следующей зависимости, которой тоже нужны особенные зависимости.

Посмотри лучше http://pimple.sensiolabs.org/, http://php-di.org/, http://symfony.com/doc/current/components/dependency_injection/index.html.
 
Последнее редактирование:
Аналог pimple я тут выкладывал, писал не зная про pimple. Сам этой реализацией и пользуюсь, чтобы не связываться с reflection, но, на самом деле, поюзав, не могу сказать, что это очень удобный подход. Из-за кучи требуемой оберточной писанины очень провоцирует на использование "как сервис локатора" - очень лениво писать все эти constructor functions, когда нужен всего-навсего вызов логгера в одном месте.

С другой стороны, yaml/xml-конфиги я в гробу видел, phemto хорош относительной лаконичностью в рамках php-кода. Именованные сервисы туда в принципе добавить легко (ввести named reuse lifecycle).
 
@Вурдалак pimple это service locator, у меня же DI. это немного разные вещи, хотя и то и то реализуют идею инверсии управления.

В общем, ни у тебя, ни у phemto нельзя получить сервис одного и того же класса с разными зависимостями

Ну а как DI угадает какие именно зависимости ты хочешь (если мы ему этого не сказали)?

Приведи пример api как ты это видишь.
 
Последнее редактирование:
Кто тебе такое сказал? У тебя путаница в понятиях.
http://habrahabr.ru/post/199296/
смотри комментарии

DI-контейнер же должен сам разбираться, кому какие аргументы конструктора вбить.
Если мы не используем интерфейсы т.е.
PHP:
class a
{
  
}

class b
{
    private $a;
    public function __construct( a $a)
    {
        $this->a = $a;
    }
}

$di->get('b');
DI сам определит, что нужно, сам создаст объект a, и вернёт уже готовый b.
ServiceLocator, так не умеет, ему нужно точно сказать что какой сервис хочет, вот и вся разница.
 
Последнее редактирование:
Комментарии на хабре - это да, это авторитетный источник.

DI от SL отличается вовсе не этим.
 
pimple не использует reflection, он не может сам определить что нужно инжектировать, а чем отличается DI от SL?
 
Сервис-локатор:

PHP:
class C {

    protected $dep;

    public function __construct() {
        $this->dep = SL::get('dep');
    }

}

$c = new C;
DI:

PHP:
class C {

    protected $dep;

    public function __construct($dep) {
        $this->dep = $dep;
    }

}

$c = DI::get('C');

Каким именно образом задается конфигурация зависимостей для DI, не имеет никакого значения.
 
Воу-воу, палехче. Основное отличие в использовании. Если ты инжектишь — это SL, если же ты вызываешь container->get() в минимуме мест (в идеале — в одном, например, при резолвинге контроллера), то тут уже DI (у всех классов зависимости будут инжектиться и никто ничего о контейнере, кроме самого фреймворка, не знает).

То, о чем мы тут говорим — это способы конфигурации DIC, это разные вещи.
 
Последнее редактирование:
Более того, DI прекрасно реализуется в языках, где нет никаких reflection - да и вообще классов с интерфейсами.
Например, pimple-подобная реализация есть в angularjs.
 
Сверху