Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to inject the @request into a service?

When I try to inject the @request into any of my services, I get this exception:

ScopeWideningInjectionException: Scope Widening Injection detected: The definition "service.navigation" references the service "request" which belongs to a narrower scope. Generally, it is safer to either move "service.navigation" to scope "request" or alternatively rely on the provider pattern by injecting the container itself, and requesting the service "request" each time it is needed. In rare, special cases however that might not be necessary, then you can set the reference to strict=false to get rid of this error.

What is the best way to proceed? Should I try to set this strict=false and how, or should I NOT inject the request service, but rather pass it to the service through my controller each time I call functions I need?

Other possibility would be to inject the kernel and take it from there, but in my service I am using only @router and @request, so injecting the whole kernel would be irrational.

like image 803
Tony Bogdanov Avatar asked Feb 17 '12 17:02

Tony Bogdanov


2 Answers

In Symfony 2.4, this has changed. Now, you can inject the 'request_stack' service.

For example:

use Symfony\Component\HttpFoundation\RequestStack;  class MyService {      protected $request;      public function setRequest(RequestStack $request_stack)     {         $this->request = $request_stack->getCurrentRequest();     }  } 

In your config.yml:

services:     my.service:         class: Acme\DemoBundle\MyService         calls:             - [setRequest, ["@request_stack"]] 

Full documentation is here: http://symfony.com/blog/new-in-symfony-2-4-the-request-stack

like image 101
Dan Blows Avatar answered Sep 21 '22 04:09

Dan Blows


I think there may have been some misunderstanding about what the official documentation says. In most cases you do want to inject the request directly with a scope="request" attribute on the service element. This makes the Scope Widening go away.

<service      id="zayso_core.openid.rpx"      class="Zayso\CoreBundle\Component\OpenidRpx" public="true" scope="request"> 

or in yml

zayso_core.openid.rpx:      class: Zayso\CoreBundle\Component\OpenidRpx     public: true     scope: request 

It's only in specific special cases such as Twig extensions where you need to inject the container.

And kernel is not even mentioned in the page on scopes. Injecting the kernel is far worse (conceptually) than injecting a container.

UPDATE: For S2.4 and newer, use @Blowski's answer below.

like image 37
Cerad Avatar answered Sep 18 '22 04:09

Cerad