自动定义服务依赖关系(自动装配)

编辑该页面

警告:你浏览的文档欧宝官网下载appob娱乐下载Symfony 3.2,不再维护。

这个页面的更新版本Symfob娱乐下载ony 6.2(当前的稳定版本)。

自动定义服务依赖关系(自动装配)

自动装配允许注册服务容器中以最小的配置。它会自动解析服务依赖关系的基础上,构造函数的typehint有用的领域快速应用程序开发在大型项目的早期阶段,当设计原型。它很容易注册一个服务图和缓解重构。

想象一下你正在构建一个API在Twitter发布状态,混淆ROT13(凯撒密码的一个特例)。

首先创建一个ROT13变压器类:

1 2 3 4 5 6 7 8 9
名称空间Acme;Rot13Transformer{公共函数变换(美元价值){返回函数美元价值);}}

现在Twitter客户端使用这个变压器:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
名称空间Acme;TwitterClient{私人美元变压器;公共函数__construct(Rot13Transformer美元变压器){美元- >变压器=美元变压器;}公共函数推特(美元用户,美元关键,美元状态){美元transformedStatus=美元- >变压器- >变换(美元状态);/ /……连接到Twitter和发送编码状态}}

DependencyInjection组件可以自动注册的依赖关系TwitterClient类的时候twitter_client服务被标记为autowired的:

  • YAML
  • XML
  • PHP
1 2 3 4
服务:twitter_client:类:Acme \ TwitterClient自动装配:真正的

自动装配子系统将探测到的依赖关系TwitterClient通过解析类的构造函数。例如它会发现这里的一个实例Rot13Transformer作为依赖项。如果现有的服务定义(且只有一个,见下文)是必需的类型,该服务将被注入。如果它不是这样(在本例中),子系统是足够聪明来自动注册一个私人服务Rot13Transformer类,并把它作为第一个参数twitter_client服务。再次,它可以工作只有一个给定类型的类。如果有几个相同类型的类,您必须使用一个显式的服务定义或注册一个默认实现。

正如您可以看到的,自动装配功能大大减少了所需的配置来定义一个服务。没有更多的参数部分!它也很容易改变的依赖关系TwitterClient类:添加或删除typehinted参数在构造函数中,您已经做到了。没有必要再搜索和编辑相关的服务定义。

这是一个典型的控制器使用twitter_client服务:

1 2 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 29 30
名称空间Acme\控制器;使用Sensio赞助\\FrameworkExtraBundle\配置\路线;使用Sensio赞助\\FrameworkExtraBundle\配置\方法;使用ob娱乐下载\\FrameworkBundle\控制器\控制器;使用ob娱乐下载\组件\HttpFoundation\请求;使用ob娱乐下载\组件\HttpFoundation\响应;使用ob娱乐下载\组件\HttpKernel\异常\BadRequestHttpException;DefaultController扩展控制器{/ * * *@Route(“/推”)*@Method(“文章”)* /公共函数tweetAction(请求美元请求){美元用户=美元请求- >请求- >get (“用户”);美元关键=美元请求- >请求- >get (“关键”);美元状态=美元请求- >请求- >get (“状态”);如果(!美元用户| | !美元关键| | !美元状态){BadRequestHttpException ();}美元- >get (“twitter_client”)- >推特(美元用户,美元关键,美元状态);返回响应(“好吧”);}}

你可以尝试API的使用旋度:

1
curl - d美元“用户= kevin&key = ABCD&status =你好”http://localhost: 8000 /条

它应该返回好吧

使用接口

你也可能发现自己使用抽象而不是实现(特别是在发展应用程序),因为它允许轻易替代一些依赖项无需修改的类不同。

遵循这些最佳实践,构造函数参数必须typehinted接口,而不是具体的类。它允许在必要时轻易替换当前的实现。它还允许使用其他变形金刚。您可以创建一个TransformerInterface只包含一个方法(变换()):

1 2 3 4 5 6
名称空间Acme;接口TransformerInterface{公共函数变换(美元价值);}

然后编辑Rot13Transformer让它实现新的接口:

1 2 3 4 5
/ /……Rot13Transformer实现了TransformerInterface{/ /……}

和更新TwitterClient依赖的接口:

1 2 3 4 5 6 7 8 9
TwitterClient{公共函数__construct(TransformerInterface美元变压器){/ /……}/ /……}

最后必须更新服务定义,因为显然,自动装配子系统不能发现自己的接口实现注册:

  • YAML
  • XML
  • PHP
1 2 3 4 5 6 7
服务:rot13_transformer:类:Acme \ Rot13Transformertwitter_client:类:Acme \ TwitterClient自动装配:真正的

自动装配子系统检测到rot13_transformer服务实现TransformerInterface并自动注入。即使使用接口(你应该),构建服务图和重构项目比标准更容易定义。

处理多个相同类型的实现

最后但并非最不重要,自动装配功能允许指定给定类型的默认实现。我们引入一个新的实现的TransformerInterface返回的结果ROT13转换大写:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
名称空间Acme;UppercaseTransformer实现了TransformerInterface{私人美元变压器;公共函数__construct(TransformerInterface美元变压器){美元- >变压器=美元变压器;}公共函数变换(美元价值){返回strtoupper (美元- >变压器- >变换(美元价值));}}

这门课是为了装饰任何变压器并返回其值大写。

控制器现在可以重构来添加一个新的端点使用这个大写的变压器:

1 2 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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
名称空间Acme\控制器;使用Sensio赞助\\FrameworkExtraBundle\配置\路线;使用Sensio赞助\\FrameworkExtraBundle\配置\方法;使用ob娱乐下载\\FrameworkBundle\控制器\控制器;使用ob娱乐下载\组件\HttpFoundation\请求;使用ob娱乐下载\组件\HttpFoundation\响应;使用ob娱乐下载\组件\HttpKernel\异常\BadRequestHttpException;DefaultController扩展控制器{/ * * *@Route(“/推”)*@Method(“文章”)* /公共函数tweetAction(请求美元请求){返回美元- >推特(美元请求,“twitter_client”);}/ * * *@Route(“/ tweet-uppercase”) *@Method(“文章”)* /公共函数tweetUppercaseAction(请求美元请求){返回美元- >推特(美元请求,“uppercase_twitter_client”);}私人函数推特(请求美元请求,美元服务){美元用户=美元请求- >请求- >get (“用户”);美元关键=美元请求- >请求- >get (“关键”);美元状态=美元请求- >请求- >get (“状态”);如果(!美元用户| | !美元关键| | !美元状态){BadRequestHttpException ();}美元- >get (美元服务)- >推特(美元用户,美元关键,美元状态);返回响应(“好吧”);}}

最后一步是更新服务定义注册这个新实现和Twitter客户端使用它:

  • YAML
  • XML
  • PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
服务:rot13_transformer:类:Acme \ Rot13Transformerautowiring_types:Acme \ TransformerInterfacetwitter_client:类:Acme \ TwitterClient自动装配:真正的uppercase_transformer:类:Acme \ UppercaseTransformer自动装配:真正的uppercase_twitter_client:类:Acme \ TwitterClient参数:(“@uppercase_transformer”)

这值得一些解释。你现在有两个服务实现TransformerInterface。自动装配子系统不能猜哪一个使用导致这样的错误:

1 2
\ob娱乐下载 \ DependencyInjection \ [Symfony \组件异常RuntimeException)无法自动装配参数的类型“Acme \ TransformerInterface”服务“twitter_client”。

幸运的是,autowiring_types关键是这里默认指定使用哪一个实现。这个密钥可以在必要时的列表类型。

由于此设置,rot13_transformer服务是自动注射作为参数的uppercase_transformertwitter_client服务。为uppercase_twitter_client,一个标准的服务定义用于注入特定的uppercase_transformer服务。

至于其他RAD特性如FrameworkBundle控制器或注释,记住不要在公共场合使用自动装配包或大型项目与复杂的维护需求。

这项工作,包括代码示例,许可下Creative Commons冲锋队3.0许可证。