Как получить экземпляр контейнера в классе администратора сонаты?

Мне нужно проанализировать некоторые параметры конфигурации из моего config.yml, такие как включенные языки. Но когда я пытаюсь сделать это с помощью обычного метода symfony: $this->container->get('my_params'); это терпит неудачу, потому что мой класс администратора расширяет класс Sonata\AdminBundle\Admin\Admin, который не расширяет класс Symfony\Component\DependencyInjection\ContainerAware.

Пожалуйста, как получить контейнер внутри класса администратора сонаты?

Теперь я решаю эту проблему, переопределяя класс администратора сонаты, чтобы он расширял ContainerAware.


person skonsoft    schedule 01.09.2012    source источник


Ответы (5)


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

$this->getConfigurationPool()->getContainer();

Конечно лучше инжектить сервисы в админке, но как и в контроллерах. зачем кому-то тратить время на настройку внедрения сеттера, если контейнер уже доступен?

person Javier Neyra    schedule 01.08.2013

Добавьте в свой класс администратора

/** @var \Symfony\Component\DependencyInjection\ContainerInterface */
private $container;

public function setContainer (\Symfony\Component\DependencyInjection\ContainerInterface $container) {
    $this->container = $container;
}

И добавьте вызовы в конфигурации сервисов (конфигурация может быть указана в YAML, XML или PHP):

YAML

calls:
    - [ setContainer, [ @service_container ] ]

XML

 <call method="setContainer">
     <argument type="service" id="service_container" />
 </call>

Теперь вы можете использовать обычный метод Symfony: $this->container->get()

Для получения дополнительной информации см. документацию Service Container.

person Максим Шатов    schedule 03.02.2013
comment
Это может не работать в пользовательском контроллере CRUD, поскольку администратор сонаты хочет выделить себя. - person Thomas Kekeisen; 10.03.2015
comment
В общем случае этот метод должен работать с любыми сервисами. см. DependencyInjection - person Максим Шатов; 10.03.2015

Вот лучший способ использования сервисов в классах администрирования сонаты:

Просто внедрите нужный сервис с помощью внедрения сеттера. Внедрение конструктора в этом случае не допускается, потому что вам придется переопределить конструктор родительского класса. Конструктор родительского класса принимает только 3 параметра, поэтому добавить еще один нельзя.

Решение:

<!-- file: services.xml -->

 <service id="skonsoft.znata.admin.keyword" class="%skonsoft.znata.admin.keyword.class%">
            <tag name="sonata.admin" manager_type="orm" group="Keyword" label="Keyword"/>
            <argument />
            <argument>%skonsoft.znata.admin.keyword.entity.class%</argument>
            <argument>SonataAdminBundle:CRUD</argument>
            <call method="setTranslationDomain">
                <argument>SkonsoftZnataBundle</argument>
            </call>

            <!-- here you inject needed services or parameters -->
            <call method="setEnabledLocales">
                <argument>%skonsoft_znata.locales%</argument>
            </call>
        </service>

Затем просто добавьте общедоступный метод в свой класс администратора с именем setEnabledLocales.

/* file: MyclassAdmin.php */

 public function setEnabledLocales($locales){
    $this->enabedLocales = $locales;
}

Взгляни на:

документация по сервис-контейнеру

person skonsoft    schedule 01.09.2012
comment
Вы можете использовать инъекцию конструктора, просто убедитесь, что конструктор класса администратора принимает $code, $class и $baseControllerName в качестве первых 3 параметров, а затем ваши пользовательские зависимости. Звоните parent::__construct($code, $class, $baseControllerName). Наконец, объявите свои пользовательские зависимости под уже настроенным разделом arguments в своих службах.[yml|xml|независимо]. - person RockTheShow; 09.10.2015

В вашей конкретной ситуации может быть целесообразно, чтобы пользовательский класс AdminController задавал параметры вашего класса Admin. Это будет соответствовать шаблону MVC и избавит вас от смены пакетов поставщиков. Если вы не знаете, как это сделать, обновите свой вопрос, и я объясню более подробно.

person likeitlikeit    schedule 01.09.2012
comment
Я решил это, внедрив сам контейнер в свой класс администратора, что является плохой частью. Я использовал внедрение сеттера вместо внедрения конструкции, потому что конструкция должна иметь точно такой же прототип родителя. - person skonsoft; 01.09.2012

Вот пример сервиса liip_imagine:

 $cacheManager = $this->getConfigurationPool()->getContainer()->get('liip_imagine.cache.manager');
person Shadi Akil    schedule 18.01.2019