phx
phx

Reputation: 21

Passing variables to Symfony2 service constructor

I have a Symfony2 application (a bridge to third party API) consisting mostly of console commands. 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.

I use Symfony DI to construct the services, and each service has public method setOrganization(Organization $organization) which is called after getting the service. E.g. (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. 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, e.g. something like security.token_storage layer, which would store something like "session information" but in a console way? What would be the best architectural and Symfony-way solution here?

Upvotes: 2

Views: 1362

Answers (2)

jiboulex
jiboulex

Reputation: 3031

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

Upvotes: 3

Wouter Sioen
Wouter Sioen

Reputation: 532

You could make the organisation a parameter of the ->doStuff() method?

This way, you should not need to call the setOrganisation anymore and remove the possibility of calling doStuff without setting the organisation first.

Upvotes: 0

Related Questions