基本上,您可以通过编写一些带有特殊名称的“标记”服务来使用 DIC。
为此,您需要将您的服务定义到一个文件中(遵循 DIC 规范)并以特定方式标记它们(在这种情况下,代码将由 Sonata Admin Bundle 获取,用于解释)
# MyBundle/Resources/config/admin.yml
services:
sonata.admin.tag:
class: YourNS\AdminBundle\Admin\BlogAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: posts, label: "Blog" }
arguments:
- ~
- YourNS\AdminBundle\Entity\Course
- 'SonataAdminBundle:CRUD'
calls:
- [ setTranslationDomain, [YourNSAdminBundle]]
在这种情况下,我定义了一个名为sonata.admin.tag 的服务,该服务带有sonata.admin 标签。
我可以用sonata.admin.tag标签名定义十几个。
完成此操作后,我必须创建一个“特殊”文件(我将把它放入 bundle 的 DependencyInjection 文件夹 [用于约定]),即 CompilerPass file。
什么是 CompilerPass 文件?
编译器通行证让您有机会操纵其他服务
已在服务容器中注册的定义。[...]
编译器传递最常见的用例之一是使用
标记的服务(在组件部分阅读有关标记的更多信息
“使用标记服务”)。
这正是你所需要的!
现在您必须搜索(在此文件中)标记为(在此特定示例中)sonata.admin 的服务
class AddDependencyCallsCompilerPass implements CompilerPassInterface
{
/**
* {@inheritDoc}
*/
public function process(ContainerBuilder $container)
{
$groupDefaults = $admins = $classes = array();
$pool = $container->getDefinition('sonata.admin.pool');
foreach ($container->findTaggedServiceIds('sonata.admin') as $id => $tags) {
foreach ($tags as $attributes) {
$definition = $container->getDefinition($id);
$arguments = $definition->getArguments();
if (strlen($arguments[0]) == 0) {
$definition->replaceArgument(0, $id);
}
if (strlen($arguments[2]) == 0) {
$definition->replaceArgument(2, 'SonataAdminBundle:CRUD');
}
$this->applyConfigurationFromAttribute($definition, $attributes);
$this->applyDefaults($container, $id, $attributes);
$arguments = $definition->getArguments();
$admins[] = $id;
//other logic here
$pool->addMethodCall('setAdminClasses', array($classes));
正如您在此处看到的,我们正在搜索标记为 sonata.admin ($container->findTaggedServiceIds('sonata.admin')) 的服务,并将这些服务(在这种情况下,专门针对奏鸣曲管理包)添加到 $pool,即 @ 987654333@
现在,我们必须将 CompilerPass 注册到我们的包文件中(您在将包注册到应用程序之前创建的那个)
class SonataAdminBundle extends Bundle
{
/**
* {@inheritDoc}
*/
public function build(ContainerBuilder $container)
{
$container->addCompilerPass(new AddDependencyCallsCompilerPass());
}
}
现在,您已经为这个捆绑包注册了某种服务。服务工厂更适合
Symfony2 的服务容器提供了一种强大的控制方式
对象的创建,允许您指定传递给的参数
构造函数以及调用方法和设置参数。
但是,有时这并不能为您提供所需的一切
来构造你的对象。
或将其视为服务实例化的“入口点”。