如何在奏鸣曲管理类中获取容器实例?
Posted
技术标签:
【中文标题】如何在奏鸣曲管理类中获取容器实例?【英文标题】:How to get container instance in sonata Admin class? 【发布时间】:2012-08-26 18:45:52 【问题描述】:我需要从我的 config.yml 中解析一些配置参数,例如启用的语言。但是当我尝试通过使用普通的 symfony 方法来做到这一点时:$this->container->get('my_params');
它失败了,因为我的管理类扩展了 Sonata\AdminBundle\Admin\Admin
类,它没有扩展 Symfony\Component\DependencyInjection\ContainerAware
类。
请问,如何在奏鸣曲管理类中获取容器?
现在我通过重写 Sonata Admin Class 以使其扩展 ContainerAware 来解决这个问题。
【问题讨论】:
【参考方案1】:可能已经解决,因为它是一个老问题,但仅供参考,容器已经在使用配置池的管理类中可用...
$this->getConfigurationPool()->getContainer();
当然,在管理类中注入服务是更好的做法,但是,就像在控制器中一样。如果容器已经可用,为什么还要花时间配置 setter 注入?
【讨论】:
管理池的getContainer()
方法自 Sonata Admin 3.77.0 起已被弃用,并已在 4.x 中删除。请参阅其他答案以了解替代(= 正确)方法。【参考方案2】:
添加到您的管理类
/** @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 文档
【讨论】:
这可能不适用于自定义 CRUD 控制器,因为奏鸣曲管理员想要自行分配。 一般情况下,此方法适用于任何服务。见DependencyInjection【参考方案3】:这是在奏鸣曲管理类中使用服务的最佳方式:
只需使用 setter 注入 注入所需的服务。在这种情况下不允许构造函数注入,因为您必须覆盖父类的构造函数。父类的构造函数只接受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;
看看:
Service Container documentation
【讨论】:
您可以使用构造函数注入,只需确保您的 Admin 类构造函数将$code
、$class
和 $baseControllerName
作为前 3 个参数,然后是您的自定义依赖项。致电parent::__construct($code, $class, $baseControllerName)
。最后,在您的服务中已配置的arguments
部分下方声明您的自定义依赖项。[yml|xml|whatever]。【参考方案4】:
在您的特定情况下,让自定义 AdminController
类设置您的 Admin
类的参数可能是明智的。这将遵循 MVC 模式,并使您免于更改供应商捆绑包。如果您不知道如何执行此操作,请更新您的问题,我会更详细地解释。
【讨论】:
我通过在我的管理类中注入容器本身解决了这个问题,这是一个不好的部分。我使用 setter 注入而不是构造注入,因为构造应该具有完全相同的父原型。【参考方案5】:这里是一个 liip_imagine 服务的例子:
$cacheManager = $this->getConfigurationPool()->getContainer()->get('liip_imagine.cache.manager');
【讨论】:
【参考方案6】:Admin Pool 的 getContainer() 方法自 Sonata Admin 3.77.0 起已被弃用,并已在 v4.x 中删除。
您可以通过 Sonata Admin 类 (v4.x) 中的依赖注入来实现这一点。
例如,我已注入 ParameterBagInterface 以在我的奏鸣曲管理员中获取应用程序参数。
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class ProtocolAdmin extends AbstractAdmin
private $params;
public function __construct(string $code, string $class, string $baseControllerName, ParameterBagInterface $params)
parent::__construct($code, $class, $baseControllerName);
$this->params = $params;
...
【讨论】:
以上是关于如何在奏鸣曲管理类中获取容器实例?的主要内容,如果未能解决你的问题,请参考以下文章