Luk*_*uke 5 configuration dependency-injection symfony
我有一个服务,让司机做实际的工作.驱动程序本身是在Symfony 2的上下文中只是另一项服务.
为了说明简化版本:
services:
# The driver services.
my_scope.mailer_driver_smtp:
class: \My\Scope\Service\Driver\SmtpDriver
my_scope.mailer_driver_mock:
class: \My\Scope\Service\Driver\MockDriver
# The actual service.
my_scope.mailer:
class: \My\Scope\Service\Mailer
calls:
- [setDriver, [@my_scope.mailer_driver_smtp]]
Run Code Online (Sandbox Code Playgroud)
如上所示,我可以将两个驱动程序服务中的任何一个注入到Mailer服务中.问题当然是注入的驱动程序服务是硬编码的.所以,我想参数化@my_scope.mailer_driver_smtp
.
我通过添加一个条目来做到这一点 parameters.yml
my_scope_mailer_driver: my_scope.mailer_driver_smtp
Run Code Online (Sandbox Code Playgroud)
然后我可以在my中使用它config.yml
并将参数分配给语义暴露配置[1]:
my_scope:
mailer:
driver: %my_scope_mailer_driver%
Run Code Online (Sandbox Code Playgroud)
最后,在Configuration
我的bundle类中,我在容器上设置了一个参数:
$container->setParameter('my_scope.mailer.driver', $config['mailer']['driver'] );
Run Code Online (Sandbox Code Playgroud)
容器参数的值my_scope.mailer.driver
现在等于my_scope.mailer_driver_smtp
我在parameters.yml
其中设置的值,因为我对它的理解是正确的,只是一个字符串.
如果我现在使用容器中的参数名称,我会收到一个错误,抱怨没有这样的服务.例如:
services:
my_scope.mailer:
class: \My\Scope\Service\Mailer
calls:
- [setDriver, [@my_scope.mailer.driver]]
Run Code Online (Sandbox Code Playgroud)
以上将导致错误:
[Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException]
The service "my_scope.mailer" has a dependency on a non-existent service "my_scope.mailer.driver"
Run Code Online (Sandbox Code Playgroud)
现在的问题是,注入这个基于容器参数的服务的正确语法是什么?
[1] http://symfony.com/doc/current/cookbook/bundles/extension.html
这个问题在这里有类似的答案
我认为使用这种定义的最佳方法是使用服务别名.
这可能看起来像这样
Acme\FooBundle\DependencyInjection\AcmeFooExtension
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration;
$config = $this->processConfiguration($configuration, $configs);
$loader = new Loader\YamlFileLoader(
$container,
new FileLocator(__DIR__.'/../Resources/config')
);
$loader->load('services.yml');
$alias = $config['mailer']['driver'];
$container->setAlias('my_scope.mailer_driver', $alias);
}
Run Code Online (Sandbox Code Playgroud)
这将别名您在定义的服务my_scope.mailer.driver
与my_scope.mailer_driver
,你可以像任何其他服务中使用
services.yml
services:
my_scope.mailer_driver:
alias: my_scope.mailer_driver_smtp # Fallback
my_scope.mailer_driver_smtp:
class: My\Scope\Driver\Smtp
my_scope.mailer_driver_mock:
class: My\Scope\Driver\Mock
my_scope.mailer:
class: My\Scope\Mailer
arguments:
- @my_scope.mailer_driver
Run Code Online (Sandbox Code Playgroud)
使用这样的设计,只要更改config.yml中的my_scope.mailer_driver
参数,服务就会更改.
请注意,如果服务不存在,扩展将抛出异常.
使用服务容器表达式语言,您可以访问配置文件中的以下两个函数:
因此,要将参数名称转换为服务引用,您需要以下内容:
parameters:
my_scope_mailer_driver: my_scope.mailer_driver_smtp
services:
my_scope.mailer:
class: \My\Scope\Service\Mailer
calls:
- [setDriver, [@=service(parameter('my_scope_mailer_driver'))]]
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2531 次 |
最近记录: |