How to call Entity Manager in a constructor? - php

I've been trying to call Entity Manager in a constructor:
function __construct()
{
$this->getDoctrine()->getEntityManager();
...
but, as I've seen in this answer: Stackoverflow question, it can't be done.
So I wonder if there is a way to achieve it, as I have to call it often, and want to do some stuff in the constructor after getting the repository.
Edit:
I've tried with #MKhalidJunaid answer:
//src/MSD/HomeBundle/Resources/config/services.yml
services:
imageTransController.custom.service:
class: MSD\HomeBundle\Controller\ImageTransController
arguments:
EntityManager: "#doctrine.orm.entity_manager"
-
//app/config/config.php
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: doctrine_extensions.yml }
- { resource: "#MSDHomeBundle/Resources/config/services.yml" }
-
//src/MSD/HomeBundle/Controller/ImageTransController.php
namespace MSD\HomeBundle\Controller;
use Doctrine\ORM\EntityManager;
use MSD\HomeBundle\Entity\Imagen as Imagen;
use MSD\HomeBundle\Controller\HomeController as HomeController;
class ImageTransController extends HomeController
{
protected $em ;
function __construct(EntityManager $entityManager)
{
...
but I'm getting this error:
Catchable Fatal Error: Catchable Fatal Error: Argument 1 passed to MSD\HomeBundle\Controller\ImageTransController::__construct() must be an instance of Doctrine\ORM\EntityManager, none given, called in /home/manolo/MiServer/itransformer/app/cache/dev/jms_diextra/controller_injectors/MSDHomeBundleControllerImageTransController.php on line 13 and defined in /home/manolo/MiServer/itransformer/src/MSD/HomeBundle/Controller/ImageTransController.php line 38 (500 Internal Server Error)
New attempt:
I've also tried with #praxmatig answer:
//services.yml
parameters:
msd.controller.imagetrans.class: MSD\HomeBundle\Controller\ImageTransController
services:
msd.imagetrans.controller:
class: "%msd.controller.imagetrans.class%"
arguments: [ #doctrine.orm.entity_manager ]
-
//ImageTransController.php
namespace MSD\HomeBundle\Controller;
use Doctrine\ORM\EntityManager;
class ImageTransController
{
protected $em ;
function __construct(EntityManager $em)
{
$this->em = $em;
}
...
-
//routing.yml
msd_home_cambiardimensiones:
pattern: /cambiardimensiones
defaults: { _controller: MSDHomeBundle:msd.imagetrans.controller:cambiardimensionesAction }
but I get this error:
Unable to find controller "MSDHomeBundle:msd.imagetrans.controller" - class "MSD\HomeBundle\Controller\msd.imagetrans.controllerController" does not exist. (500 Internal Server Error)

You need to make a service for your class and pass the doctrine entity manager as the argument doctrine.orm.entity_manager.Like in services.yml
services:
test.cutom.service:
class: Test\YourBundleName\Yourfoldernameinbundle\Test
#arguments:
arguments: [ #doctrine.orm.entity_manager ]
#entityManager: "#doctrine.orm.entity_manager"
You must import your services.yml in config.yml
imports:
- { resource: "#TestYourBundleName/Resources/config/services.yml" }
Then in your class's constructor get entity manager as argument
use Doctrine\ORM\EntityManager;
Class Test {
protected $em;
public function __construct(EntityManager $entityManager)
{
$this->em = $entityManager;
}
}
Hope this makes sense

Don't extend the base controller class when you register controller as a service. There is a documentation about it here
class ImageTestController
{
private $em;
public function __construct(EntityManager $em)
{
$this->em = $em;
}
public function someAction()
{
// do something with $this->em
}
}
// services.yml
services:
acme.controller.image_test:
class: Acme\SomeBundle\Controller\ImageTestController
// routing.yml
acme:
path: /
defaults: { _controller: acme.controller.image_test:someAction }

Why do you want to grab the Doctrine 2 EntityManager in the constructor of a controller?
Why not simply do $em = $this->getDoctrine()->getManager(); (or $em = $this->getDoctrine()->getEntityManager(); in Symfony 2.0) in the action(s) you need it? This saves you from the overhead of initializing the EntityManager when you don't need it.
If you really do want to do this, there are clear instructions on How to define Controllers as Services. Basically it looks like this:
# src/MSD/HomeBundle/Controller/ImageTransController.php
namespace MSD\HomeBundle\Controller;
use Doctrine\ORM\EntityManager;
class ImageTransController
{
private $em;
public function __construct(EntityManager $em)
{
$this->em = $em;
}
public function indexAction()
{
// use $this->em
}
}
# src/MSD/HomeBundle/Resources/config/services.yml
parameters:
msd.controller.image_trans.class: MSD\HomeBundle\Controller\ImageTransController
services:
msd.controller.image_trans:
class: "%msd.controller.image_trans.class%"
arguments: ["#doctrine.orm.default_entity_manager"]
# app/config/routing.yml
msd_home_cambiardimensiones:
path: /cambiardimensiones
defaults: { _controller: msd.controller.image_trans:indexAction }

You have to add
use Doctrine\ORM\EntityManager;
in your controller

I see that you are trying to get the entity manager in the constructor of the controller, which is not the way to do so , unless you plan to define your controller as a service.
which on this case, you need to use dependency injection to inject the service entity manager.
But in general the common way to use entity manager in a controller is simply by getting it using the following code:
$entityManager = $this->container->get('doctrine.orm.entity_manager');

I think you are in the right direction, I would take the second option:
For the second option I think that the definition inside routing.yml is wrong
//routing.yml
msd_home_cambiardimensiones:
pattern: /cambiardimensiones
defaults: { _controller: msd.imagetrans.controller:cambiardimensionesAction }
Here just remove MSDHomeBundle from the _controller inside defaults
For the first option:
Does HomeController has its own constructor?
//src/MSD/HomeBundle/Resources/config/services.yml
services:
imageTransController.custom.service:
class: MSD\HomeBundle\Controller\ImageTransController
arguments: [#doctrine]
it could help then inside the constructor
__construct(Registry $doctrine)
$this->doctrine = $doctrine;
or
$this->em = $doctrine->getManager();

Related

Call to a member function getRepository() on string

I created symfony service as described here: Symfony2: get Doctrine in a generic PHP class
Service.yml
app.lib.helpers:
class: AppBundle\Lib\Helpers
arguments: [doctrine.orm.entity_manager]
Class Helpers
class Helpers
{
protected $em;
public function __construct($entityManager)
{
$this->em = $entityManager;
}
public function checkStatuses()
{
$orderId = $this->em->getRepository('AppBundle:Orders')->findAll();
}
}
In controller action
$helper = $this->get('app.lib.helpers');
$helper->checkStatuses();
But im getting error:
Error: Call to a member function getRepository() on string
What causes that problem?
I think it should be
arguments: [ "#doctrine.orm.entity_manager" ]
in your Service.yml
Your service definition not correct, try this or you can read this for more explain http://symfony.com/doc/current/service_container.html:
app.lib.helpers:
class: AppBundle\Lib\Helpers
arguments: [#doctrine.orm.entity_manager]

#doctrine.orm.entity_manager not being given to a class registered as a service

I am trying to create a service in Symfony2 to automatically pass Doctrine\ORM\EntityManager to __construct to avoid having to pass it each time I instantiate the class, i.e.
// use this
$TestClass= new TestClass;
// instead of this
$entityManager = $this->getDoctrine()->getEntityManager();
$TestClass= new TestClass($entityManager);
I created a class EntityManagerUser, tried to register it as a service and TestClass extends that.
services.yml is included, as another service works, and I've double-checked by adding (then removing) a syntax error.
I read the docs, this, this and this and I've ended up with the code below, which doesn't pass #doctrine.orm.entity_manager. However, the controller_listener service does receive #templating.
I've cleared cache via the console and manually deleted app/cache but I still see this error:
ContextErrorException: Catchable Fatal Error: Argument 1 passed to Test\TestBundle\ServiceUser\EntityManagerUser::__construct() must be an instance of Test\TestBundle\ServiceUser\Doctrine\ORM\EntityManager, none given, called in D:\Documents\www\Test\live\src\Test\TestBundle\Controller\MyController.php on line 84 and defined in D:\Documents\www\Test\live\src\Test\TestBundle\ServiceUser\EntityManagerUser.php line 14
services.yml
services:
# this one doesn't throw an error and passes #templating to __construct
test.eventlistener.before_controller_listener:
class: Test\TestBundle\Eventlistener\BeforeControllerListener
arguments: [ #templating ]
tags:
- { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
# the following one doesn't pass #doctrine.orm.entity_manager
test.service_user.entity_manager_user:
class: Test\TestBundle\ServiceUser\EntityManagerUser
arguments: [ #doctrine.orm.entity_manager ]
src/Test/TestBundle/ServiceUser/EntityManagerUser.php
namespace Test\TestBundle\ServiceUser;
use Doctrine\ORM\EntityManager;
class EntityManagerUser{
protected $entityManager;
public function __construct(EntityManager $entityManager){
$this->entityManager = $entityManager;
// N.B. it's not possible to do it this way:
// $this->entityManager = new EntityManager;
}
// also tried public function __construct($entityManager){
// and public function __construct(Doctrine\ORM\EntityManager $entityManager){
}
src/Test/TestBundle/Classes/TestClass.php
namespace Test\TestBundle\Classes\TestClass;
use Test\TestBundle\ServiceUser\EntityManagerUser;
class TestClass extends EntityManagerUser{
/* currently no functions */
}
In my controller, line 84
$test= new TestClass;
// I tested that this throws the same error, it does // $test= new EntityManagerUser;
What have I missed?
Services only get their arguments if they are called through the service constructor:
$this->get('test.service_user.entity_manager_user');
Declaring the class as a service doenst make a difference if you create a new class and extend the original.
What you could do is also declare this new class as a service and still have it extend the base class.
test.classes.test_class:
class: Test\TestBundle\Classes\TestClass\TestClass
arguments: [ #doctrine.orm.entity_manager ]
then you dont have to define the constructor in the extended class because it is the parent.
then get the class by doing:
$testClass = $this->get('test.classes.test_class');
//will be instanceof Test\TestBundle\Classes\TestClass\TestClass
I worked out how to do what I wanted, which was not define entityManager each time I was required in an instanciated class.
It made sense to rename EntityManagerUser to ContainerListener, a static class, and inject #service_container into it through services, so it can then also return other classes.
namespace Test\TestBundle\EventListener;
class ContainerListener{
static $container;
// knock out the parent::onKernelRequest function that we don't want
public function onKernelRequest($event){
return;
}
public function __construct($container){
self::$container = $container;
}
static function twig(){
return self::$container->get('twig');
}
static function entityManager(){
return self::$container->get('doctrine')->getEntityManager();
}
static function entityManagerConnection(){
$entityManager = self::$container->get('doctrine')->getEntityManager();
return $entityManager->getConnection();
}
}
services.yml
services:
test.event_listener.container_listener:
class: Test\TestBundle\EventListener\ContainerListener
arguments: [ #service_container ]
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
BaseClass.php gets entityManager
namespace Test\TestBundle\Class;
use Test\TestBundle\EventListener\ContainerListener;
class BaseClass{
public function __construct(){
$this->entityManager = ContainerListener::entityManager();
}
}
TestClass.php extends BaseClass as do others
class TestClass extends BaseClass(){
function someFunction(){
// etc etc
// $this->entityManager exists with no construct and without passing it
$stmt = $this->entityManager->getConnection()->prepare( $some_sql );
// etc etc
}
}
Somewhere in DefaultController.php
# nope # $entityManager = $this->getDoctrine()->getEntityManager();
# nope # $TestClass= new TestClass($entityManager);
$TestClass= new TestClass; # win!

What is the best way to inject EventDispatcher in EntityRepository?

I would like to know what is the best practice for EventDispatcher injection in EntityRepository class.
First, using global is a very bad practice. I strongly advise you not to do this.
Second, Injecting services into a repository doesn't seem like a good idea. It will often break laws like the Single Responsibility Principle.
I'd create a manager that will wrap the methods of your repository, and will trigger the events you need. See how to inject repository to a service for further information.
services.yml
services:
my_manager:
class: Acme\FooBundle\MyManager
arguments:
- #acme_foo.repository
- #event_dispatcher
acme_foo.repository:
class: Acme\FooBundle\Repository\FooRepository
factory_service: doctrine.orm.entity_manager
factory_method: getRepository
arguments:
- "AcmeFooBundle:Foo"
Acme\FooBundle\MyManager
use Acme\FooBundle\Repository\FooRepository;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
class MyManager
{
protected $repository;
protected $dispatcher;
public function __construct(FooRepository $repository, EventDispatcherInterface $dispatcher)
{
$this->repository = $repository;
$this->dispatcher = $dispatcher;
}
public function findFooEntities(array $options = array())
{
$event = new PreFindEvent;
$event->setOptions($options);
$this->dispatcher->dispatch('find_foo.pre_find', $event);
$results = $this->repository->findFooEntities($event->getOptions());
$event = new PostFindEvent;
$event->setResults($results);
$this->dispatcher->dispatch('find_foo.post_find', $event);
return $event->getResults();
}
}
Then you can use it in your controller, just like a service.
$this->get('my_manager')->findFooEntities($options);
However, if you really need to inject the event dispatcher into your entity, you can do this
services.yml
services:
acme_foo.repository:
class: Acme\FooBundle\Repository\FooRepository
factory_service: doctrine.orm.entity_manager
factory_method: getRepository
arguments:
- "AcmeFooBundle:Foo"
calls:
- [ "setEventDispatcher", [ #event_dispatcher ] ]
Then you just have to add the setEventDispatcher method to your repository.
Acme\FooBundle\Repository\FooRepository
class FooRepository extends EntityRepository
{
protected $dispatcher;
public function setEventDispatcher(EventDispatcherInterface $dispatcher)
{
$this->dispatcher = $dispatcher;
}
public function findFooEntities(array $options = array())
{
$dispatcher = $this->dispatcher;
// ...
}
}
Just make sure you call the service and not the repository when using it in the controller.
DO
$this->get('acme_foo.repository')->findFooEntities();
DON'T
$this->getDoctrine()->getManager()->getRepository('AcmeFooBundle:Foo')->findFooEntities();

How to get Doctrine to work inside a helper function on Symfony2

I need to get doctrine working inside my helper, im trying to use like i normaly do in a controller:
$giftRepository = $this->getDoctrine( )->getRepository( 'DonePunctisBundle:Gift' );
But this gave me:
FATAL ERROR: CALL TO UNDEFINED METHOD
DONE\PUNCTISBUNDLE\HELPER\UTILITYHELPER::GETDOCTRINE() IN
/VAR/WWW/VHOSTS/PUNCTIS.COM/HTTPDOCS/SRC/DONE/PUNCTISBUNDLE/HELPER/UTILITYHELPER.PH
What Im missing here?
EDIT:
services file
services:
templating.helper.utility:
class: Done\PunctisBundle\Helper\UtilityHelper
arguments: [#service_container]
tags:
- { name: templating.helper, alias: utility }
Firts lines of helper file
<?php
namespace Done\PunctisBundle\Helper;
use Symfony\Component\Templating\Helper\Helper;
use Symfony\Component\Templating\EngineInterface;
class UtilityHelper extends Helper {
/*
* Dependency injection
*/
private $container;
public function __construct( $container )
{
$this->container = $container;
}
The problem here is that your Helper class is not container-aware; that is, it has no idea about all the services Symfony has loaded (monolog, twig, ...and doctrine).
You fix this by passing "doctrine" to it. This is called Dependency Injection, and is one of the core things that makes Symfony awesome. Here's how it works:
First, give your Helper class a place for the Doctrine service to live, and require it in the Helper's constructor:
class UtilityHelper
{
private $doctrine;
public function __construct($doctrine)
{
$this->doctrine = $doctrine;
}
public function doSomething()
{
// Do something here
}
}
Then, you use services.yml to define how Symfony should construct that instance of Helper:
services:
helper:
class: Done\PunctisBundle\Helper\UtilityHelper
arguments: [#doctrine]
In this case, #doctrine is a placeholder that means "insert the Doctrine service here".
So now, in your Controller, or in anything else that is container-aware, you can get access to Doctrine through the Helper class like this:
class SomeController()
{
public function someAction()
{
$this->get("helper")->doctrine->getRepository(...);
}
}
EDIT
After looking at your edit, it appears that you're injecting the entire service container into the Helper class. That's not a best practice -- you should only inject what you need. However, you can still do it:
services.yml
services:
helper:
class: Done\PunctisBundle\Helper\UtilityHelper
arguments: [#service_container]
UtilityHelper.php
class UtilityHelper
{
private $container;
public function __construct($container)
{
$this->container = $container;
}
public function doSomething()
{
// This won't work, because UtilityHelper doesn't have a getDoctrine() method:
// $this->getDoctrine()->getRepository(...)
// Instead, think about what you have access to...
$container = $this->container;
// Now, you need to get Doctrine
// This won't work... getDoctrine() is a shortcut method, available only in a Controller
// $container->getDoctrine()->getRepository(...)
$container->get("doctrine")->getRepository(...)
}
}
I've included a few comments there that highlight some common pitfalls. Hope this helps.
In Helper, Services etc you cannot use it like in actions.
You need to pass it like argument to youre Helper via service description in conf file(services.yml or *.xml).
Example:
services:
%service_name%:
class: %path_to_youre_helper_class%
arguments: [#doctrine.orm.entity_manager]
tags:
- { name: %name% }
And dont forget catch it in __construct of youre Helper.
Example:
use Doctrine\ORM\EntityManager;
....
private $em;
public function __construct(EntityManager $em)
{
$this->em = $em;
}
You can use it like:
public function myMethod()
{
$repo = $this->em->getRepository('DonePunctisBundle:Gift');
}

How to inject a repository into a service in Symfony?

I need to inject two objects into ImageService. One of them is an instance of Repository/ImageRepository, which I get like this:
$image_repository = $container->get('doctrine.odm.mongodb')
->getRepository('MycompanyMainBundle:Image');
So how do I declare that in my services.yml? Here is the service:
namespace Mycompany\MainBundle\Service\Image;
use Doctrine\ODM\MongoDB\DocumentRepository;
class ImageManager {
private $manipulator;
private $repository;
public function __construct(ImageManipulatorInterface $manipulator, DocumentRepository $repository) {
$this->manipulator = $manipulator;
$this->repository = $repository;
}
public function findAll() {
return $this->repository->findAll();
}
public function createThumbnail(ImageInterface $image) {
return $this->manipulator->resize($image->source(), 300, 200);
}
}
Here is a cleaned up solution for those coming from Google like me:
Update: here is the Symfony 2.6 (and up) solution:
services:
myrepository:
class: Doctrine\ORM\EntityRepository
factory: ["#doctrine.orm.entity_manager", getRepository]
arguments:
- MyBundle\Entity\MyClass
myservice:
class: MyBundle\Service\MyService
arguments:
- "#myrepository"
Deprecated solution (Symfony 2.5 and less):
services:
myrepository:
class: Doctrine\ORM\EntityRepository
factory_service: doctrine.orm.entity_manager
factory_method: getRepository
arguments:
- MyBundle\Entity\MyClass
myservice:
class: MyBundle\Service\MyService
arguments:
- "#myrepository"
I found this link and this worked for me:
parameters:
image_repository.class: Mycompany\MainBundle\Repository\ImageRepository
image_repository.factory_argument: 'MycompanyMainBundle:Image'
image_manager.class: Mycompany\MainBundle\Service\Image\ImageManager
image_manipulator.class: Mycompany\MainBundle\Service\Image\ImageManipulator
services:
image_manager:
class: %image_manager.class%
arguments:
- #image_manipulator
- #image_repository
image_repository:
class: %image_repository.class%
factory_service: doctrine.odm.mongodb
factory_method: getRepository
arguments:
- %image_repository.factory_argument%
image_manipulator:
class: %image_manipulator.class%
In case if do not want to define each repository as a service, starting from version 2.4 you can do following, (default is a name of the entity manager):
#=service('doctrine.orm.default_entity_manager').getRepository('MycompanyMainBundle:Image')
Symfony 3.3, 4 and 5 makes this much simpler.
Check my post How to use Repository with Doctrine as Service in Symfony for more general description.
To your code, all you need to do is use composition over inheritance - one of SOLID patterns.
1. Create own repository without direct dependency on Doctrine
<?php
namespace MycompanyMainBundle\Repository;
use Doctrine\ORM\EntityManagerInterface;
use MycompanyMainBundle\Entity\Image;
class ImageRepository
{
private $repository;
public function __construct(EntityManagerInterface $entityManager)
{
$this->repository = $entityManager->getRepository(Image::class);
}
// add desired methods here
public function findAll()
{
return $this->repository->findAll();
}
}
2. Add config registration with PSR-4 based autoregistration
# app/config/services.yml
services:
_defaults:
autowire: true
MycompanyMainBundle\:
resource: ../../src/MycompanyMainBundle
3. Now you can add any dependency anywhere via constructor injection
use MycompanyMainBundle\Repository\ImageRepository;
class ImageService
{
public function __construct(ImageRepository $imageRepository)
{
$this->imageRepository = $imageRepository;
}
}
In my case bases upon #Tomáš Votruba answer and this question I propose the following approaches:
Adapter Approach
Without Inheritance
Create a generic Adapter Class:
namespace AppBundle\Services;
use Doctrine\ORM\EntityManagerInterface;
class RepositoryServiceAdapter
{
private $repository=null;
/**
* #param EntityManagerInterface the Doctrine entity Manager
* #param String $entityName The name of the entity that we will retrieve the repository
*/
public function __construct(EntityManagerInterface $entityManager,$entityName)
{
$this->repository=$entityManager->getRepository($entityName)
}
public function __call($name,$arguments)
{
if(empty($arrguments)){ //No arguments has been passed
$this->repository->$name();
} else {
//#todo: figure out how to pass the parameters
$this->repository->$name(...$argument);
}
}
}
Then foreach entity Define a service, for examplein my case to define a (I use php to define symfony services):
$container->register('ellakcy.db.contact_email',AppBundle\Services\Adapters\RepositoryServiceAdapter::class)
->serArguments([new Reference('doctrine'),AppBundle\Entity\ContactEmail::class]);
With Inheritance
Same step 1 mentioned above
Extend the RepositoryServiceAdapter class for example:
namespace AppBundle\Service\Adapters;
use Doctrine\ORM\EntityManagerInterface;
use AppBundle\Entity\ContactEmail;
class ContactEmailRepositoryServiceAdapter extends RepositoryServiceAdapter
{
public function __construct(EntityManagerInterface $entityManager)
{
parent::__construct($entityManager,ContactEmail::class);
}
}
Register service:
$container->register('ellakcy.db.contact_email',AppBundle\Services\Adapters\RepositoryServiceAdapter::class)
->serArguments([new Reference('doctrine')]);
Either the case you have a good testable way to function tests your database beavior also it aids you on mocking in case you want to unit test your service without the need to worry too much on how to do that. For example, let us suppose we have the following service:
//Namespace definitions etc etc
class MyDummyService
{
public function __construct(RepositoryServiceAdapter $adapter)
{
//Do stuff
}
}
And the RepositoryServiceAdapter adapts the following repository:
//Namespace definitions etc etc
class SomeRepository extends \Doctrine\ORM\EntityRepository
{
public function search($params)
{
//Search Logic
}
}
Testing
So you can easily mock/hardcode/emulate the behavior of the method search defined in SomeRepository by mocking aither the RepositoryServiceAdapter in non-inheritance approach or the ContactEmailRepositoryServiceAdapter in the inheritance one.
The Factory Approach
Alternatively you can define the following factory:
namespace AppBundle\ServiceFactories;
use Doctrine\ORM\EntityManagerInterface;
class RepositoryFactory
{
/**
* #param EntityManagerInterface $entityManager The doctrine entity Manager
* #param String $entityName The name of the entity
* #return Class
*/
public static function repositoryAsAService(EntityManagerInterface $entityManager,$entityName)
{
return $entityManager->getRepository($entityName);
}
}
And then Switch to php service annotation by doing the following:
Place this into a file ./app/config/services.php (for symfony v3.4, . is assumed your ptoject's root)
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
$definition = new Definition();
$definition->setAutowired(true)->setAutoconfigured(true)->setPublic(false);
// $this is a reference to the current loader
$this->registerClasses($definition, 'AppBundle\\', '../../src/AppBundle/*', '../../src/AppBundle/{Entity,Repository,Tests,Interfaces,Services/Adapters/RepositoryServiceAdapter.php}');
$definition->addTag('controller.service_arguments');
$this->registerClasses($definition, 'AppBundle\\Controller\\', '../../src/AppBundle/Controller/*');
And cange the ./app/config/config.yml (. is assumed your ptoject's root)
imports:
- { resource: parameters.yml }
- { resource: security.yml }
#Replace services.yml to services.php
- { resource: services.php }
#Other Configuration
Then you can clace the service as follows (used from my example where I used a Dummy entity named Item):
$container->register(ItemRepository::class,ItemRepository::class)
->setFactory([new Reference(RepositoryFactory::class),'repositoryAsAService'])
->setArguments(['$entityManager'=>new Reference('doctrine.orm.entity_manager'),'$entityName'=>Item::class]);
Also as a generic tip, switching to php service annotation allows you to do trouble-free more advanced service configuration thin one above. For code snippets use a special repository I made using the factory method.
For Symfony 5 it is really simple, without need of services.yml to inject the dependency:
inject the Entity Manager in the service constructor
private $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}
Then get the repository :
$this->em->getRepository(ClassName::class)
by replacing ClassName with your entity name.

Categories