繁体   English   中英

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

[英]Symfony3.4: How to specify a service with an argument

在 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;
    }

服务.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/ }'

    App\Ahi\Sp\AdminBundle\Controller\:
        resource: '../../src/Ahi/Sp/AdminBundle/Controller'
        public: true
        tags: ['controller.service_arguments']

    admin.brandeventService:
      autowire: true
      autoconfigure: true
      class: 'App\Ahi\Sp\AdminBundle\Model\Service\BrandEventService'

    App\Ahi\Sp\AdminBundle\Controller\Hq\DefaultController:
      arguments: [ '@admin.brandeventService' ]

    App\Ahi\Sp\AdminBundle\Model\Service\BrandEventService: '@admin.brandeventService'

当前代码中的错误

Service "admin.brandeventService" not found:  
even though it exists in the app's container,  
the container inside "App\Ahi\Sp\AdminBundle\Controller\Hq\DefaultController"  
is a smaller service locator that only knows about the "doctrine"

试过的代码

  • 将 $brandEventService 添加到 articleService 的 __construct
  • 将 __construct 和 $brandEventService 添加到 DefaultController
  • 在 services.yml 中的 DefaultController 中设置服务
  • 添加 BrandEventService $brandEventService 到 getArticleSummary

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            App\Ahi\Sp\AdminBundle\Model\Service\BrandEventService  
  Tags             -                                                       
  Public           no                                                      
  Synthetic        no                                                      
  Lazy             no                                                      
  Shared           yes                                                     
  Abstract         no                                                      
  Autowired        yes                                                     
  Autoconfigured   yes                                                     
 ---------------- -------------------------------------------------------- 

您应该像这样修改您的services.yaml

services:
  _defaults:
    autowire: true
    autoconfigure: true

  admin.shopeventService:
    autowire: true
    autoconfigure: true
    public: true
    class: App\Admin\Media\Provider\MultiUploadFileProvider

    # ...

    App\Ahi\Sp\AdminBundle\Model\Service\ShopEventService: '@admin.shopeventService'


    # same here
    # ...
   App\Ahi\Sp\AdminBundle\Model\Service\BrandEventService: '@admin.brandeventService'

有关更多详细信息,您可以查看此链接https://symfony.com/doc/current/service_container/autowiring.html#using-aliases-to-enable-autowiring

希望这会有所帮助。

答案基于问题的上下文。 这里的目标是将旧版 Symfony 2 应用程序最终更新到 4.4。 试图在不重写太多应用程序的情况下让代码在 3.4 下运行。

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

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);
    }

上面的代码显示了将两个服务添加到控制器的服务定位器,然后在操作方法中拉动其中一个。 services.yaml 文件只是开箱即用的基本配置。 不需要别名或调整。 这应该足以让你继续前进。

一旦您了解这里发生了什么,您就可以返回 go 并阅读有关服务定位器的部分,并可能了解处理此问题的“正确”方法。 但这实际上可能要等到 4.4,因为 Symfony 4 中引入了一些改进。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM