10

クラスModelsRepositoryがあります:

class ModelsRepository extends EntityRepository
{}

そしてサービス

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

ModelsRepository からサービス container_data へのアクセスを取得したい。コンストラクターを使用したコントローラーからサービスを送信できません。

あなたはそれを行う方法を知っていますか?

4

8 に答える 8

13

私見、 SRPデメテルの法則などのルールを簡単に破る可能性があるため、これは必要ありません

しかし、本当に必要な場合は、次の方法があります。

まず、「setContainer」呼び出しを持つ基本「ContainerAwareRepository」クラスを定義します。

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 ] ]

ContainerAwareRepository は次のようになります

AcmeBundle\Repository\ContainerAwareRepository.php

abstract class ContainerAwareRepository extends EntityRepository
{
    protected $container;

    public function setContainer(ContainerInterface $container)
    {
        $this->container = $container;
    }
}

次に、モデル リポジトリを定義します。
ここでは、getRepositoryリポジトリを構築するためにドクトリンのメソッドを使用します

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

そして、クラスを定義するだけです

AcmeBundle\Repository\ModelsRepository.php

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

リポジトリを使用するには、まずサービスから呼び出す必要があります。

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

しかし、あなたが直接行う場合

$em->getRepository('AcmeBundle:Models')->findFoo(); // Fatal error, container is undefined
于 2013-07-02T16:56:20.733 に答える
7

いくつかのバージョンを試しました。問題は次のように解決されました

モデルリポジトリ:

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

その結果、必要に応じてコンテナを使用できるリポジトリを取得しました。しかし、この認識は重大な場合にのみ使用できます。これは、リポジトリに制限があるためです。Thx 4all。

于 2012-10-19T12:11:12.620 に答える
4

レポからサービスにアクセスするのは良い考えですか?

リポジトリはカスタム SQL 用に設計されており、doctrine の場合、doctrine はfind(), findOne(), findBy(), [...] 「魔法の」メソッドを支援します。

リポジトリを使用する場所にサービスを注入することを考慮し、いくつかのパラメーターが必要な場合は、リポジトリのメソッドに直接渡します。

于 2012-10-19T10:27:56.617 に答える
4

これは絶対に必要な場合にのみ行うべきであることに強く同意します。現在可能な非常に単純なアプローチがありますが (Symfony 2.8 でテスト済み)。

  1. リポジトリに実装する「ContainerAwareInterface」
  2. 「ContainerAwareTrait」を使用する
  3. services.yml を調整する

リポジトリ クラス:

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'
于 2017-12-08T10:28:43.087 に答える
0

Laurynas Mališauskas の回答を拡張して、コンストラクターにサービスを渡すには、リポジトリもサービスにして、引数を付けて渡します。

models.repository:
      class: ModelsRepository
      arguments: ['@service_you_want_to_pass']
于 2012-10-19T10:08:15.483 に答える
0

最も簡単な方法は、サービスをリポジトリ コンストラクターに挿入することです。

class ModelsRepository extends EntityRepository
{
  private $your_service;

  public function __construct(ProjectName\MyBundle\Common\Container $service) {
    $this->your_service = $service;
  } 
}
于 2012-10-19T10:05:29.920 に答える