【问题标题】:Passing variables to Symfony2 service constructor将变量传递给 Symfony2 服务构造函数
【发布时间】:2015-12-16 12:23:01
【问题描述】:

我有一个 Symfony2 应用程序(连接第三方 API 的桥梁),主要由控​​制台命令组成。每个控制台命令都有一个“organizationId”参数,用于解析 API 的各种选项,例如 API 密钥、url、可用语言等。应用程序中 90% 的服务使用这些参数来调用 API 或获取/在本地数据库中存储数据。

我使用Symfony DI来构建服务,每个服务都有公共方法setOrganization(Organization $organization),获取服务后调用。例如。 (简化代码):

protected function execute(InputInterface $input, OutputInterface $output)
{
    $organization = $this
        ->getContainer()
        ->get('doctrine')
        ->getRepository('CoreBundle:Organization')
        ->find($input->getArgument('organizationId'));

    $personService = $this->getContainer()
        ->get('person')
        ->setOrganization($organization); // I want to get rid of this
    $personService->doStuff();
}

服务定义:

person:
    class: AppBundle\Services\Person
    arguments: ["@buzz", "@doctrine.orm.entity_manager", "@organization_settings_resolver", "%media_service%"]

我正在寻找一种重构代码的方法,以便在使用任何服务时都无需调用setOrganization()。是否可以在不传递整个服务容器的情况下将对象或命令行参数传递给构造函数? 也许应该有不同的方法,例如security.token_storage 层之类的东西,它会以控制台方式存储诸如“会话信息”之类的东西? 这里最好的架构和 Symfony 方式的解决方案是什么?

【问题讨论】:

  • 简短的回答是否定的,您不能将参数传递给容器。您可以尝试使用命令事件 (symfony.com/doc/current/components/console/events.html),这将允许您在调用命令执行之前创建一个侦听器来设置人员服务。类似于内核事件的作用。我自己从来没有试过。可能不值得努力。

标签: php symfony dependency-injection


【解决方案1】:

在服务定义中,你可以在初始化时调用服务的方法,这样就可以避免在获取后调用它:

person:
    class: AppBundle\Services\Person
    arguments: ["@buzz", "@doctrine.orm.entity_manager", "@organization_settings_resolver", "%media_service%"]
    calls:
        - [ setOrganization,[ @your_organization ] ]

这是如果 your_organisation 是已定义且可用的服务

【讨论】:

  • 在这种情况下,组织依赖于输入参数,因此不能作为服务使用。
【解决方案2】:

您可以将组织作为->doStuff() 方法的参数吗?

这样,您应该不再需要调用 setOrganisation 并消除在不先设置组织的情况下调用 doStuff 的可能性。

【讨论】:

    猜你喜欢
    • 2013-10-09
    • 2020-01-16
    • 1970-01-01
    • 1970-01-01
    • 2021-05-15
    • 1970-01-01
    • 2012-01-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多