25

In the controller, I could do

$this->get('service.name') 

But in a custom class, how can I do that?

5 Answers 5

27

Define your custom class as a service, and then inject dependencies into it.

Ex:

// services.yml services: my.custom.service.id: class: My\Custom\Class arguments: - @service.name - @doctrine.orm.entity_manager 

Your custom class' constructor would then get those services as arguments.

Be sure to read up on the Service Container in the official docs. It goes over all this in great detail.

Sign up to request clarification or add additional context in comments.

Comments

9

You were on the right track with ContainerAware.

$this->get('id') is actually a shortcut to $this->container->get('id'). And getting container into your class is as simple as implementing ContainerAwareInterface - putting this snippet into your class:

public function setContainer(\Symfony\Component\DependencyInjection\ContainerInterface $container = null) { $this->container = $container; } 

8 Comments

To whoever put -1: I'd really like an explanation why do you think my answer was wrong and what is the right answer. Keep in mind that question was basically: "how to inject service container into custom class?"
I'm not the one who downvoted, but the original question was how to access a service in a custom class, not how to inject the service container (which is considered bad practice.)
He asked how to access services in a custom class, not how to inject a certain service into it, he even gave an example from controller and was looking himself into ways to replicate the behaviour. Downvoting a perfectly right answer only because it is situationally bad practice is very wrong since we were not given a full use case to decide. So I really hope that wasn't the reasoning behind -1.
This is also kinda the right answer. $this->get() is from the container and if you have container available in your custom controller you can access services. Best practice is to inject container via "yourController extends ContainerAware". Thats it
Best Practice - collective agreement that X is the best know solution to problem Y. It's possible for them to change, though rarely, as in the case of the Service Locator (SL) pattern which was superseded by Dependency Injection (DI) Containers (DIC) with regards to dependency resolution. SL is even considered an anti-pattern by some Engineers. In this case configuring your controller as a service (Symfony not Web) practices DI, while the container aware approach practices SL. A controller like any object should receive it's dependencies from an external source via it's interface.
|
0

If you do not know the full list of dependencies that you need at the moment when the service is created, you can pass the container as the argument http://symfony.com/doc/current/book/service_container.html#using-the-expression-language

services: service_name: class: AppBundle\Class arguments: ['@=container'] 

Comments

-1

Accessing the service container in a custom class (not in a service defined class)

This is not best practice to do, but it works. If your custom class is not set to be a service then you can access the service container using global variable $kernel:

class Helper { private $container; /** * Constructor assigns service container to private container. */ public function __construct() { global $kernel; $this->container = $kernel->getContainer(); } function doSOmething() { $someService = $this->container->get('service.name'); // do something with someService ... } } 

1 Comment

it works... so this is a valid solution not best practice but still
-3

OK I suppose @Arms answer is a possible solution, I found by looking at the source to Controller, I could extend ContainerAware

2 Comments

Keep in mind that if you extend ContainerAware you need to manually set the container object. If you're instantiating your custom class somewhere that doesn't have access to the container, this won't be possible.
Injecting the whole container is a bad idea. Inject each service you need in your service explicitly.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.