Symfony3.4:如何使用参数指定服务



在Symfony3.4中,在支持自动连接时发生以下错误。
如果使用$articleType和显示相应文章的现有代码指定服务名称,则会出现以下错误。
将多个服务传递给__construct不起作用。有什么好办法吗?

https://symfony.com/doc/3.4/service_container/3.3-di-changes.html
Controller.php

private function getArticleSummary($articleType)
{
$summary = array();
$articleService = $this->get('admin.'.$articleType.'Service');
foreach (array('draft', 'pending', 'reject', 'publish', 'hidden') as $articleStatus) {
$params = array(
'articleType' => $articleType,
'articleStatus' => $articleStatus,
);
$summary[$articleStatus] = $articleService->countArticleBySearchParams($params);
}
return $summary;
}

services.yml

services:
_defaults:
autowire: true
autoconfigure: true
public: false
App:
resource: '../../src/*'
exclude: '../../src/{Entity,Repository, Ahi/Sp/AdminBundle/Resources/public/uploadify, Ahi/Sp/AdminBundle/Ahi/Sp/PublicBundle/ }'
AppAhiSpAdminBundleController:
resource: '../../src/Ahi/Sp/AdminBundle/Controller'
public: true
tags: ['controller.service_arguments']
admin.brandeventService:
autowire: true
autoconfigure: true
class: 'AppAhiSpAdminBundleModelServiceBrandEventService'
AppAhiSpAdminBundleControllerHqDefaultController:
arguments: [ '@admin.brandeventService' ]
AppAhiSpAdminBundleModelServiceBrandEventService: '@admin.brandeventService'

当前代码错误

Service "admin.brandeventService" not found:  
even though it exists in the app's container,  
the container inside "AppAhiSpAdminBundleControllerHqDefaultController"  
is a smaller service locator that only knows about the "doctrine"

尝试代码

  • 添加$ branddeventservice到articleService的__construct
  • 添加__construct和$brandEventService到DefaultController
  • 在services.yml
  • 中设置DefaultController中的service
  • 添加BrandEventService $ BrandEventService到getarticlesumary

DefaultController.php

protected $brandEventService;
public function __construct(BrandEventService $brandEventService)
{
$this->brandEventService = $brandEventService;
}

php bin/console debug:container admin.brandeventService试验结果

Information for Service "admin.brandeventService"
=================================================
---------------- -------------------------------------------------------- 
Option           Value                                                   
---------------- -------------------------------------------------------- 
Service ID       admin.brandeventService                                 
Class            AppAhiSpAdminBundleModelServiceBrandEventService  
Tags             -                                                       
Public           no                                                      
Synthetic        no                                                      
Lazy             no                                                      
Shared           yes                                                     
Abstract         no                                                      
Autowired        yes                                                     
Autoconfigured   yes                                                     
---------------- -------------------------------------------------------- 

答案取决于问题的上下文。这里的目标是将遗留的Symfony 2应用程序最终更新到4.4。试图让代码在3.4下运行,而不重写太多的应用程序。

基本问题是,当使用Symfony的AbstractController类时,只能使用$this->get()访问特定的服务。您可以查看源代码以了解发生了什么,但实际上使用ServiceSubscriberInterface::getSubscribedServices()方法来指定可用的服务。因此,解决此问题的最快方法是将文章类型服务添加到派生控制器:

class DefaultController extends AbstractController
{
public static function getSubscribedServices() : array
{
$services = parent::getSubscribedServices();
$services['admin.brand'] = BrandEventService::class;
$services['admin.other'] = OtherEventService::class;
return $services;
}
public function type(string $type = null) : Response
{
$serviceId = 'admin.' . $type;
$service = $this->get($serviceId);
return new Response('Article Type ' . $type);
}

上面的代码显示了向控制器的服务定位器添加两个服务,然后在一个动作方法中提取其中一个。服务。Yaml文件只是基本的开箱即用配置。不需要别名或调整。这应该足够让你继续下去了。

一旦你明白了这里发生了什么,你就可以回去阅读服务定位器部分,也许就会明白处理这个问题的"正确"方法。但这实际上可以等到4.4版本,因为Symfony 4中引入了一些改进。

你应该这样修改你的services.yaml:

services:
_defaults:
autowire: true
autoconfigure: true
admin.shopeventService:
autowire: true
autoconfigure: true
public: true
class: AppAdminMediaProviderMultiUploadFileProvider
# ...
AppAhiSpAdminBundleModelServiceShopEventService: '@admin.shopeventService'

# same here
# ...
AppAhiSpAdminBundleModelServiceBrandEventService: '@admin.brandeventService'

更多详细信息请参见此链接https://symfony.com/doc/current/service_container/autowiring.html#using-aliases-to-enable-autowiring

希望这对你有帮助。

最新更新