简体   繁体   English

将变量传递给Symfony2服务构造函数

[英]Passing variables to Symfony2 service constructor

I have a Symfony2 application (a bridge to third party API) consisting mostly of console commands. 我有一个Symfony2应用程序(与第三方API的桥梁),主要由控​​制台命令组成。 Each console command takes an "organizationId" argument which is used to resolve various options of the API, such as API key, url, available languages etc. 90% of services in the application use these parameters either for calling the API, or for fetching/storing data in the local database. 每个控制台命令都带有一个“ organizationId”参数,该参数用于解析API的各种选项,例如API密钥,URL,可用语言等。应用程序中90%的服务使用这些参数来调用API或获取/存储本地数据库中的数据。

I use Symfony DI to construct the services, and each service has public method setOrganization(Organization $organization) which is called after getting the service. 我使用Symfony DI构建服务,每个服务都有公共方法setOrganization(Organization $organization) ,该方法在获取服务后会被调用。 Eg (simplified code): 例如(简化代码):

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

Service definition: 服务定义:

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

I am looking for a way to refactor code so that I don't need to call setOrganization() whenever I use any service. 我正在寻找一种重构代码的方法,以便在使用任何服务时都不需要调用setOrganization() Is it possible to pass an object or a command line parameter to the constructor without passing the whole service container? 是否可以在不传递整个服务容器的情况下将对象或命令行参数传递给构造函数? Maybe there should be a different approach, eg something like security.token_storage layer, which would store something like "session information" but in a console way? 也许应该有一个不同的方法,例如security.token_storage层之类的方法,它将以控制台方式存储“会话信息”之类的信息? What would be the best architectural and Symfony-way solution here? 这里最好的建筑和Symfony方式解决方案是什么?

In a service definition, you can call a method of the service in the initilisation, thus you can avoid calling it after getting it : 在服务定义中,您可以在初始化中调用服务的方法,因此可以避免在获得服务后调用它:

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

This is if your_organisation is a defined and available service 如果your_organisation是已定义且可用的服务

You could make the organisation a parameter of the ->doStuff() method? 您可以使组织成为->doStuff()方法的参数吗?

This way, you should not need to call the setOrganisation anymore and remove the possibility of calling doStuff without setting the organisation first. 这样,您无需再调用setOrganisation并消除在不首先设置组织的情况下调用doStuff的可能性。

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

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