简体   繁体   中英

Adding doctrine entity manager to service in symfony2

Im trying to add entity manager to my service layer in Symfony. I've researched online but none of the answers seem to work for me.

I have a class with a namespace called AppBundle\\Controller. My class name is MasterController. Then what exactly do I need to add into my services.yml?

Other than that I think I only need to pass EntityManager $em into the constructor as a param and then assign $em to $this->em (private)?

Eg

class MasterController extends Controller
{
    private $em;

    public function __construct(EntityManager $em)
    {
        $this->em = $em;
    } 
}

It's possible to define controllers as services while at the same time, extending the framework controller class. Why do this? By doing this you can take advantage of the base functionality such as the form factory, template rendering, get user stuff etc.

At the same time, you can inject any controller specific services you need. This avoids using the container as a service locator pattern. In other words, we can push services into the controller as opposed to having the controllers pull the services. The controllers don't need to care where the services come from and become more self contained.

Example:

class PersonController extends Controller
{
    private $personRepository;

    public function __construct($personRepository)
    {
        $this->personRepository = $personRepository;
    }
    public function editAction(Request $request, $id)
    {
        $person = $this->personRepository->find($id); 

        $form = $this->createForm(new PersonFormType(), $person);

        $form->handleRequest($request);

        if ($form->isValid()) {

            // Note: I add flush/persist methods to my repositories
            // You could inject the entity manager and flush from it
            $personRepository->flush();

            return $this->redirect($this->generateUrl('wherever'));
        }

        return $this->render('person/edit.html.twig', array(
        'form' => $form->createView(),));
    }
}

Make the controller a service with:

services:
person_repository:
    class: AppBundle\Entity\PersonRepository
    factory_service: 'doctrine.orm.default_entity_manager'
    factory_method:  'getRepository'
    arguments:  
        - 'AppBundle\Entity\Person'

person_controller:
    class: AppBundle\Controller\PersonController
    calls:
      - [setContainer,['@service_container']]
    arguments: 
      -'person_repository

So basically, you end up with a standard Symfony controller with all the standard functionality but you can inject controller specific services such as repositories which in turn makes your controllers easier to read and debug. You should never need to use $this->get('service') from within your controller action methods.

Contract this with the more standard method of retrieving an entity:

$personRepository = $this->getDoctrine()->getManager()->getRepository('AppBundle\Entity\Person');

As you can see, the standard method not only ties the controller directly to doctrine but also requires the controller to know the entity's class name. You can decide which method is easier to write, understand and maintain.

First of all if your MasterController extends Symfony\\Bundle\\FrameworkBundle\\Controller class then you have already EntityManager available by using:

$this->em = $this->getDoctrine();

But if you want to inject it by yourself to your constructor (and have Controller as a service ) all you need to do is have entry in your services.yml like this:

services:
    your_controller_service:
        class: AppBundle\Controller\MasterController
        arguments: [@doctrine.orm.entity_manager]

And that's it.

EDIT :

Remember that you need to have use Doctrine\\ORM\\EntityManager somewhere before your class definition to avoid Catchable fatal error

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM