Конструктор виджетов
Re: Конструктор виджетов
roxblnfk, ясно, спасибо за подробный ответ.
-
- Сообщения: 910
- Зарегистрирован: 2019.08.13, 01:49
Re: Конструктор виджетов
Я думаю было бы логично, если бы фабрика в методе create использовала бы композитный контейнер из контейнера полученного через конструктор и самой фабрики(как контейнера), естественно с приоритетом фабрики(как контейнера) (не помню что там за чем для этого добавлять в композитном контейнере). Тогда при создании фабрики мы можем установить/переопределить локальные зависимости для объектов, создаваемых этой фабрикой, не изменяя при этом глобальный/внедренный контейнер, но его зависимости по-прежнему будут доступны. По факту композитный контейнер должен создаваться в конструкторе фабрики и записываться в $this->container.
У вас же, если установлен контейнер в конструкторе фабрики, то берется он, если нет - то используется фабрика как контейнер
Вот в ArrayBuilder
Код: Выделить всё
private function resolveDependencies(ContainerInterface $container, array $dependencies): array
{
$container = $container->container ?? $container;
//...
}
Код: Выделить всё
$provider = new \Yiisoft\EventDispatcher\Provider\Provider();
$dispatcher = new \Yiisoft\EventDispatcher\Dispatcher($provider);
WidgetFactory::initialize(null, [
EventDispatcherInterface::class => $dispatcher
]);
то все отлично заработает, потому как теперь как контейнер используется сама фабрика с нашим определением своего диспетчера.
Если есть какие-то причины/кейсы использования фабрики как исключительно локального контейнера, то объясните, если вас не затруднит.
-
- Сообщения: 910
- Зарегистрирован: 2019.08.13, 01:49
Re: Конструктор виджетов
Решение проблемы.
В классе Yiisoft\Factory\Factory меняем три метода на
В классе Yiisoft\Factory\Definitions\ArrayBuilder удаляем строку
И в Yiisoft\Di\CompositeContainer еще исправьте, замените на это (нужно при формировании списка контейнеров из внешнего источника, когда может прийти null, это как раз наш случай)
Добил исправления, тесты все проходят. Выше не все исправлено, сделаю PR.
В классе Yiisoft\Factory\Factory меняем три метода на
Код: Выделить всё
public function __construct(ContainerInterface $container = null, array $definitions = [])
{
$compositeContainer = new CompositeContainer();
$compositeContainer->attach($container);
$compositeContainer->attach($this);
$this->container = $compositeContainer;
$this->setMultiple($definitions);
}
public function create($config, array $params = [])
{
return Normalizer::normalize($config)->resolve($this->container, $params);
}
public function get($id, array $params = [])
{
return $this->getDefinition($id)->resolve($this->container, $params);
}
Код: Выделить всё
$container = $container->container ?? $container;
Код: Выделить всё
public function attach(?ContainerInterface $container): void
{
if (isset($container)) {
array_unshift($this->containers, $container);
}
}