Symfony2: How to access to service from repository

后端 未结 8 1711
有刺的猬
有刺的猬 2020-12-31 13:08

I have class ModelsRepository:

class ModelsRepository extends EntityRepository
{}

And service

container_data:
 class:               


        
8条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-12-31 13:57

    IMHO, this shouldn't be needed since you may easily break rules like SRP and Law of Demeter

    But if you really need it, here's a way to do this:

    First, we define a base "ContainerAwareRepository" class which has a call "setContainer"

    services.yml

    services:
        # This is the base class for any repository which need to access container
        acme_bundle.repository.container_aware:
            class: AcmeBundle\Repository\ContainerAwareRepository
            abstract: true
            calls:
                - [ setContainer, [ @service_container ] ]
    

    The ContainerAwareRepository may looks like this

    AcmeBundle\Repository\ContainerAwareRepository.php

    abstract class ContainerAwareRepository extends EntityRepository
    {
        protected $container;
    
        public function setContainer(ContainerInterface $container)
        {
            $this->container = $container;
        }
    }
    

    Then, we can define our Model Repository.
    We use here, the doctrine's getRepository method in order to construct our repository

    services.yml

    services:
        acme_bundle.models.repository:
            class: AcmeBundle\Repository\ModelsRepository
            factory_service: doctrine.orm.entity_manager
            factory_method:  getRepository
            arguments:
                - "AcmeBundle:Models"
            parent:
                acme_bundle.repository.container_aware
    

    And then, just define the class

    AcmeBundle\Repository\ModelsRepository.php

    class ModelsRepository extends ContainerAwareRepository
    {
        public function findFoo()
        {
            $this->container->get('fooservice');
        }
    }
    

    In order to use the repository, you absolutely need to call it from the service first.

    $container->get('acme_bundle.models.repository')->findFoo(); // No errors
    $em->getRepository('AcmeBundle:Models')->findFoo(); // No errors
    

    But if you directly do

    $em->getRepository('AcmeBundle:Models')->findFoo(); // Fatal error, container is undefined
    

提交回复
热议问题