How can I access a service outside of a controller with Symfony2? How can I access a service outside of a controller with Symfony2? symfony symfony

How can I access a service outside of a controller with Symfony2?


The Symfony distribution relies heavily on dependency injection. This means that usually, dependencies are injected directly into your object via the constructor, the setters or via other means (like reflection over properties). Your API wrapper service is then a dependency for other objects of your application.

That being said, it would be rather difficult to inject this service in an entity repository's constructor because it already requires some other parameters and I think it would not be possible to inject them because of the way we request the repository for an entity.

What you could do is to create another service which will be responsible of doing the work you were about to do in the entity repository. This way, you will be able to inject the entity manager, which will be used to retrieve the entity repository, you custom service and also another service holding your configuration values (There are other ways to share configuration values).

In my use case, I use a Facebook helper service that wraps Facebook API calls. This service is then injected where I need it. My entity repository is only responsible of doing database calls so it receives only the arguments it needs and not the whole dependency. Thus, it will not receive the helper but rather only the arguments needed to do a request, for example, a Facebook user id. In my opinion, this is the way to do it since I think the entity repository should not have dependencies on such helper objects.

Here a small example using YAML as the configuration:

# app/config/config.ymlservices:  yourapp.configuration_container:    class: Application/AcmeBundle/Common/ConfigurationContainer    # You could inject configurations here        yourapp.api_wrapper:    class: Application/AcmeBundle/Service/ApiWrapperService    # Inject other arguments if needed and update constructor in consequence      yourapp.data_access:    class: Application/AcmeBundle/Data/Access/DatabaseAccessService    arguments:       entityManager: "@doctrine.orm.entity_manager"      apiWrapperService: "@yourapp.api_wrapper"      configuration: "@yourapp.configuration_container"# Application/AcmeBundle/Common/ConfigurationContainer.phppublic ConfigurationContainer{   public function __construct()   {       // Initialize your configuration values or inject them in the constructor   }}        # Application/AcmeBundle/Service/ApiWrapperService.phppublic ApiWrapperService{   public function __construct()   {       // Do some stuff   }}# Application/AcmeBundle/Data/Access/DatabaseAccessService.phppublic DatabaseAccessService{    public function __construct(EntityManager $entityManager, ApiWrapperService $apiWrapperService, ConfigurationContainer $configuration)    {        ...    }}

The at sign (@) in the config.yml file means that Symfony should inject another service ,having the id defined after the at sign, and not a simple string. For the configuration values, as I said previously, there is other means to achieve the same goal like using parameters or a bundle extension. With a bundle extension, you could define the configuration values directly into the config.yml and your bundle would read them.

In conclusion, this should give you the general idea of injecting services. Here a small list of documentation on the subject. Alot of links use the XML service definition instead of the YAML definition but you should be able to understand them quite easily.

  1. Symfony Official DI
  2. Fabien Potencier's articles on DI
  3. Richard Miller's articles on DI (Check in his blog for the other DI articles)

Take note that the configuration I'm giving is working for Beta1 of Symfony2. I didn't update yet to Beta2 so there could be some stuff not working as they are in the Beta2 version.

I hope this will help you defining a final solution to your problem. Don't hesitate to ask other questions if you want clarifications or anything else.

Regards,Matt


I would wrap this kind of behavior in a Symfony service(like a manager).i would not inject any parameters or logic into the entity repositories, as they should mainly be used to fetch data using object manager queries.I would put the logic in the services and if the service , require a database access it will call the entity repository to fetch data.