Symfony欧宝娱乐app下载地址 3.3新增功能:服务定位器
2017年5月4日·发表的哈维尔Eguiluz
警告:这篇文章是关于一个不受支持的Symfony版本。欧宝娱乐app下载地址有些信息可能已经过时了。阅读最新的Symfony文档欧宝娱乐app下载地址.
在Sy欧宝娱乐app下载地址mfony应用程序中,一些服务需要访问其他几个服务,尽管其中一些实际上不会被使用(例如FirewallMap
类)。实例化所有这些未使用的服务是无用的,但是不可能使用显式依赖注入将它们转换为惰性服务。
在这些情况下,传统的解决方案是注入整个服务容器,以获得真正需要的服务。但是,不建议这样做,因为这样服务对应用程序的其余部分的访问范围太广,而且它隐藏了服务的实际依赖关系。
服务定位器设计模式是这样的吗“封装获取服务的过程[…]]使用被称为服务定位器的中央注册表.通常不鼓励使用这种模式,但它在这些情况下很有用,而且比注入整个服务容器要好得多。
考虑一个CommandBus
映射命令及其处理程序的类。这个类一次只处理一个命令,所以实例化所有这些命令是没有用的。首先,使用new定义一个服务定位器服务container.service_locator
标记并添加所有命令作为参数:
1 2 3 4 5 6 7 8 9
# app / config / services.yml服务:app.command_handler_locator:类:欧宝娱乐app下载地址Symfony \ \ DependencyInjection \ ServiceLocator组件标签:(“container.service_locator”)参数:-AppBundle \ FooCommand:“@app.command_handler.foo”AppBundle \ BarCommand:“@app.command_handler.bar”
然后,将服务定位器注入到为命令总线定义的服务中:
1 2 3 4
# app / config / services.yml服务:AppBundle \ CommandBus:参数:(“@app.command_handler_locator”)
的实例欧宝娱乐app下载地址Symfony \ \ DependencyInjection \ ServiceLocator组件
.这个类实现PSR-11ContainerInterface
,包括有()
而且get ()
从定位器中检查和获取服务的方法:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
/ /……使用Psr\容器\ContainerInterface;类CommandBus{/**@varContainerInterface * /私人$handlerLocator;/ /……公共函数处理(命令$命令){$commandClass= get_class ($命令);//检查一些服务是否包含在服务定位器中如果(!$这->handlerLocator->有($commandClass)) {返回;}//从服务定位器获取服务(并实例化它)$处理程序=$这->handlerLocator->get ($commandClass);返回$处理程序->处理($命令);}}
发表在#生活在边缘
评论
@Max关于服务定位器的文档已经发布,他们更详细地解释了事情://www.oldmanjams.com/doc/master/service_container/service_locators.html欧宝娱乐app下载地址
安德烈Hristov
2017年5月5日说在07:21
你是否认为传递一个lambda是可行的,它绑定了服务定位器,所以当lambda执行时,它将返回服务对象?如果没有执行,那么什么都不会发生。
评论截止。
为了确保评论保持相关性,旧帖子将被关闭。
通常都可以这样做遇到的边情况是什么?
另外,确保在该命令总线中抛出异常
Guillaume Loulier is a certified Symfony engineer.
Get certified! Online exams available in all countries.
Register Now我总是说允许访问服务内部的服务容器。yml文件是一个坏主意,我更喜欢使用私有服务来限制控制器的调用能力,并将我需要的服务从一个服务输入到另一个服务。
对我来说,这个解决方案似乎允许一个工厂服务返回许多服务,这是一个坏主意(因为,服务容器在某些情况下允许相同的方法),在我看来,工厂服务包含整个注入的服务声明,这样,所有需要这个工厂服务的服务都可以访问该方法,就像服务是由services.yml手动注入的一样。
对于命令的特殊情况,我宁愿只在服务中直接注入我需要的服务。Yml定义,而不是使用“工厂”谁为我注入:/