Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony2: How to access to service from repository

Tags:

php

symfony

I have class ModelsRepository:

class ModelsRepository extends EntityRepository
{}

And service

container_data:
 class:        ProjectName\MyBundle\Common\Container
 arguments:    [@service_container]

I want get access from ModelsRepository to service container_data. I can't transmit service from controller used constructor.

Do you know how to do it?

like image 895
Alastor Avatar asked Oct 19 '12 09:10

Alastor


People also ask

Why Symfony 3 3 3 repository as service?

Mostly due to traditional registration of Doctrine repositories. The way out from service locators to repository as service was described by many before and now we put it into Symfony 3.3 context. This post is follow up to StackOverflow answer to clarify key points and show the sweetest version yet.

How do I ask for a service in Symfony?

The moment you start a Symfony app, your container already contains many services. These are like tools: waiting for you to take advantage of them. In your controller, you can "ask" for a service from the container by type-hinting an argument with the service's class or interface name.

How do Symfony type-hints work?

When you use these type-hints in your controller methods or inside your own services, Symfony will automatically pass you the service object matching that type. Throughout the docs, you'll see how to use the many different services that live in the container.

What can we do with commands in Symfony?

One of the most usual things that we do with commands in Symfony, is the simple fact of modifying stuff on the database according to specific conditions in our application. Accessing the database through the entity manager in controller and services is quite simple and easy to do.


2 Answers

I strongly agree that this should only be done when absolutely necessary. Though there is a quite simpler approach possible now (tested with Symfony 2.8).

  1. Implement in your repository "ContainerAwareInterface"
  2. Use the "ContainerAwareTrait"
  3. adjust the services.yml

RepositoryClass:

namespace AcmeBundle\Repository;

use Doctrine\ORM\EntityRepository;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
use AcmeBundle\Entity\User;

class UserRepository extends EntityRepository implements ContainerAwareInterface
{

    use ContainerAwareTrait;

    public function findUserBySomething($param)
    {
        $service = $this->container->get('my.other.service');
    }

}

services.yml:

acme_bundle.repository.user:
    lazy: true
    class: AcmeBundle\Repository\UserRepository
    factory: ['@doctrine.orm.entity_manager', getRepository]
    arguments:
        - "AcmeBundle:Entity/User"
    calls:
        - method: setContainer
          arguments:
            - '@service_container'
like image 126
con Avatar answered Sep 21 '22 20:09

con


I tried some versions. Problem was solved follows

ModelRepository:

class ModelRepository extends EntityRepository
{
    private $container;

    function __construct($container, $em) {
        $class = new ClassMetadata('ProjectName\MyBundle\Entity\ModelEntity');
        $this->container = $container;

        parent::__construct($em, $class);
    }
}

security.yml:

providers:
    default:
        id: model_auth

services.yml

model_auth:
    class: ProjectName\MyBundle\Repository\ModelRepository
    argument

As a result I got repository with ability use container - as required. But this realization can be used only in critical cases, because she has limitations for Repository. Thx 4all.

like image 28
Alastor Avatar answered Sep 21 '22 20:09

Alastor