如何布置服务
编辑本页如何布置服务
当覆盖现有定义时,原始服务将丢失:
- YAML
- XML
- PHP
1 2 3 4 5 6 7 8
#配置/ services.yaml服务:App \梅勒:~#这将用新的App\Mailer定义替换旧的App\Mailer定义#旧定义丢失App \梅勒:类:App \ NewMailer
大多数时候,这正是你想要做的。但有时,你可能想要装饰旧的(即应用装饰器模式).在这种情况下,应该保留旧服务,以便能够在新服务中引用它。这个配置替换了App \梅勒
用一个新的,但把旧的作为参考在
:
- 属性
- YAML
- XML
- PHP
1 2 3 4 5 6 7 8 9 10 11
/ / src / DecoratingMailer.php名称空间应用程序;/ /……使用ob娱乐下载\组件\DependencyInjection\属性\AsDecorator;# (AsDecorator(装修:梅勒::类))类DecoratingMailer{/ /……}
6.1
的# (AsDecorator)
属性在Symfony 6.1中引入。ob娱乐下载
的装修
选项告诉容器App \ DecoratingMailer
服务替换App \梅勒
服务。如果你在用默认的服务。yaml的配置,当装饰服务的构造函数使用装饰服务类暗示一个参数类型时,就会自动注入装饰服务。
如果你没有使用自动装配,或者装饰服务有多个构造函数参数类型暗示了装饰服务类,你必须显式地注入装饰服务(装饰服务的ID会自动更改为“。”
):
- 属性
- YAML
- XML
- PHP
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/ / src / DecoratingMailer.php名称空间应用程序;/ /……使用ob娱乐下载\组件\DependencyInjection\属性\AsDecorator;使用ob娱乐下载\组件\DependencyInjection\属性\MapDecorated;# (AsDecorator(装修:梅勒::类))类DecoratingMailer{私人$内心的;公共函数__construct(# (MapDecorated)$内心的){$这->内心的=$内心的;}/ /……}
提示
装饰的可见性App \梅勒
服务(这是新服务的别名)将仍然与原始服务相同App \梅勒
可见性。
请注意
生成的内部id基于装饰器服务的id (App \ DecoratingMailer
这里),而不是装饰的服务(App \梅勒
这里)。控件控制内部服务名decoration_inner_name
选择:
- YAML
- XML
- PHP
1 2 3 4 5 6
#配置/ services.yaml服务:App \ DecoratingMailer:#……decoration_inner_name:App \ DecoratingMailer.wooz参数:(“@App \ DecoratingMailer.wooz”)
装饰的优先级
类对服务应用多个装饰器时,可以控制它们的顺序decoration_priority
选择。取值为整数,默认为0
更高的优先级意味着更早地应用装饰器。
- 属性
- YAML
- XML
- PHP
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
/ /……使用ob娱乐下载\组件\DependencyInjection\属性\AsDecorator;使用ob娱乐下载\组件\DependencyInjection\属性\MapDecorated;#[AsDecorator(装饰:Foo::class,优先级:5)]类酒吧{私人$内心的;公共函数__construct(# (MapDecorated)$内心的){$这->内心的=$内心的;}/ /……}#[AsDecorator(装饰:Foo::class,优先级:1)]类巴兹{私人$内心的;公共函数__construct(# (MapDecorated)$内心的){$这->内心的=$内心的;}/ /……}
生成的代码如下所示:
1
$这->服务(Foo::类]=新巴兹(新栏(新Foo ()));
叠加修饰符
使用装饰优先级的另一种选择是创建一个堆栈
订购的服务,一个接一个
- YAML
- XML
- PHP
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
#配置/ services.yaml服务:decorated_foo_stack:栈:-类:巴兹参数:(“@.inner”)-类:酒吧参数:(“@.inner”)-类:喷火使用简短的语法:decorated_foo_stack:栈:-记者:(“@.inner”)-栏:(“@.inner”)-Foo:~#可以在启用autowiring时简化:decorated_foo_stack:栈:-记者:~-栏:~-Foo:~
结果将与前一节相同:
1
$这->服务(“decorated_foo_stack”] =新巴兹(新栏(新Foo ()));
比如别名,a堆栈
只能使用公共
而且弃用
属性。
每一帧堆栈
可以是内联服务、引用或子定义。后者允许嵌入堆栈
定义相互转换,这里有一个合成的高级示例:
- YAML
- XML
- PHP
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16
#配置/ services.yaml服务:some_decorator:类:App \装饰embedded_stack:栈:-别名:some_decorator-App \装饰:~decorated_foo_stack:栈:-家长:embedded_stack-记者:~-栏:~-Foo:~
结果将是:
1
$这->服务(“decorated_foo_stack”] =新App \装饰(新App \装饰(新巴兹(新栏(新Foo ()))));
请注意
要改变现有的堆栈(即从编译器传递),你可以通过它生成的id访问每一帧,其结构如下:.stack_id.frame_key
.从上面的例子中,.decorated_foo_stack.1
将是一个内联的引用巴兹
服务和.decorated_foo_stack.0
到嵌入式堆栈。为了获得更明确的id,你可以给每一帧命名:
- YAML
- XML
- PHP
1 2 3 4 5 6 7 8
#……decorated_foo_stack:栈:第一:家长:embedded_stack第二:记者:~#……
的巴兹
帧id现在是.decorated_foo_stack.second
.
当被装饰的服务不存在时控制行为
当您装饰一个不存在的服务时,decoration_on_invalid
选项允许你选择要采取的行为。
有三种不同的行为:
异常
:一个ServiceNotFoundException
将抛出,告诉该装饰器的依赖项丢失。(默认)忽略
:容器将移除装饰器。零
:容器将保持decorator服务,并将被装饰的服务设置为零
.
- 属性
- YAML
- XML
- PHP
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/ /……使用ob娱乐下载\组件\DependencyInjection\属性\AsDecorator;使用ob娱乐下载\组件\DependencyInjection\属性\MapDecorated;使用ob娱乐下载\组件\DependencyInjection\ContainerInterface;#[AsDecorator(decorator: Mailer::class, onInvalid: ContainerInterface::IGNORE_ON_INVALID_REFERENCE)]类酒吧{私人$内心的;公共函数__construct(# (MapDecorated)$内心的){$这->内心的=$内心的;}/ /……}
谨慎
当使用零
,你可能需要更新装饰器的构造函数,以使装饰依赖为空:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/ / src /服务/ DecoratorService.php名称空间应用程序\服务;使用Acme\OptionalBundle\服务\OptionalService;类DecoratorService{私人$装饰;公共函数__construct(?OptionalService$装饰){$这->装饰=$装饰;}公共函数tellInterestingStuff():字符串{如果(!$这->装饰){返回“只有一件有趣的事”;}返回$这->装饰->tellInterestingStuff()。“+一个更有趣的事情”;}}
请注意
有时,您可能希望添加一个编译器通道,以便动态地创建服务定义。如果您想装饰这样一个服务,请确保您的编译器通道已注册PassConfig: TYPE_BEFORE_OPTIMIZATION
键入,以便装饰通道能够找到创建的服务。