Symfony 3: Inject entity repository into service controller
In this post I’m going to explain how to inject a specific entity repository into a controller defined as a service. We assume that you already created a Doctrine entity and a repository (we are calling it MyEntity here).
The Controller
We define a simple controller that offers a JSON REST-API endpoint with all the entities we saved in our database. Because we wish to use the dependency injection, we have to define the controller as a service.
<?php # src/AppBunlde/Controller/MyServiceName.php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\JsonResponse;
/**
* Very important is the Route annotation with service parameter!
* @Route("/api/myentity", service="my_service_name")
*/
class MyServiceName {
private $repository;
public function __construct(MyEntityRepository $repository) {
$this->repository = $repository;
}
/**
* @Route("/")
*/
public function someAction() {
$entities = $this->repository->findAll();
$response = new JsonResponse();
$response->setContent(json_encode($entities));
return $response;
}
}
?>
Watch out for the Route annotation on the class! Otherwise you’ll later get an exception like this:
Catchable Fatal Error: Argument 1 passed to AppBundle\Controller\MyServiceName::__construct() must be an instance of AppBundle\Repository\MyEntityRepository, none given, called in /.../var/cache/dev/classes.php on line 2081 and defined
This happens because Symfony does not instantiate the controller as a service via dependency injection, but rather as it would a normal class by plainly calling the constructor.
Register the service
Now we register the service and configure what to inject.
# app/config/services.yml
services:
my_service_name:
class: AppBundle\Controller\MyServiceName
arguments: ["@=service('doctrine.orm.entity_manager').getRepository('AppBundle:MyEntity')"]
So we just declare our controller as a service and use Symfony´s expression syntax to boil down the dependency to our MyEntityRepository.
Further reading
Checkout why we have to use the Route annotation when we define a controller as a service.