How to Get a Service from the Container Directly, If I Didn'T/Couldn't Inject the Service Using Di

How do I get a service from the container directly, if I didn't/couldn't inject the service using DI?

You need to add your dependencies so the service locator can find them.

Add a method getSubscribedServices() to your controller class:

public static function getSubscribedServices()
{
return array_merge(
parent::getSubscribedServices(),
[
'checker' => Checker::class,
]
);
}

If your controller class extends AbstractController you can simply do:

$this->get('checker');

If you want to do it in another type of class (e.g. a service that doesn't extend AbstractController), then you need to declare that your service implements the ServiceSubscriberInterface.

use Symfony\Contracts\Service\ServiceSubscriberInterface;
use Psr\Container\ContainerInterface;

class FooService implements ServiceSubscriberInterface {

public function __construct(ContainerInterface $locator)
{
$this->locator = $locator;
}

public static function getSubscribedServices() { /* same as before */ }

public function get($service)
{
return $this->locator->get($service);
}
}

... and you would be able to do the same than you in the controller earlier.

Selecting one of many services as the service to use

Actually, I believe you were on the right track with the third bullet point in the "What I've tried so far" section, except that the service container does register itself as a service, but it's called service_container, not container.

How to prevent entities from being listed as services in the container?

it is expected.

have a look at config/services.yaml where the magic happens (at least this happens in my services.yaml):

# removed lines for readability before, after and in-between the following
services:
App\:
resource: '../src/*'
exclude: '../src/{Entity,Migrations,Tests}'

this essentially should turn everything except for entities, migrations and tests in the src directory into services. you can adapt this to your needs obviously.

So essentially ... if you remove that App\ entry, you would be bound to explicitly add whitelist all classes that are supposed to be services.

Blacklisting on the other hand is shown in the example, although the example is quite general. Maybe there are more sophisticated ways to do this ...

Service not found: even though it exists in the app's container

A lot of things changed in symfony4 vs previous versions. You are using everything as if in a previous version. The quick solution is not the "preferred" way, but to start can change the public key from the default false to true in your services.yaml file.

A better way is to leave it private and use dependency injection instead. The naming of the service has changed as well (now just the path of the service). See the docs here. For your code, try these:

// services.yaml

services:
_defaults:
autowire: true
autoconfigure: true
public: false

App\Foo\Bar:
tags: { ** }

And the controller with dependence injection:

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class MyController extends AbstractController
{
public function baz(Request $request, Bar $bar)
{
$bar->doSomething();
}
}

There's a nice tutorial about these things (and more) here.



Related Topics



Leave a reply



Submit