在我的存储库类中注入容器

时间:2016-02-09 19:57:56

标签: symfony

我尝试在我的RepositoryClass中注入Container,但它不起作用。

BaseRepository:

<?php

namespace MyApp\ApplicationBundle\Repository;

use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

class BaseRepository implements ContainerAwareInterface
{

    protected $container;

    public function setContainer(ContainerInterface $container=null)
    {
        echo "container";
        var_dump($container);
    }

    public function __construct()
    {
        echo __CLASS__;
    }
}

services.yml

services:
    myapp.base_repository:
        class: MyApp\ApplicationBundle\Repository\BaseRepository
        calls:
            - [ setContainer, [ '@service_container' ] ]

DefaultController:

$baseRep = new BaseRepository();

我得到的唯一输出是来自BaseRepository Construct的echo FILE 。 我尝试的第二种方式是注入GuzzleClient self(这就是我试图注入容器的原因,因为我需要我的guzzle-configuraton-settings。

services.yml

myapp.base_repository:
    class: MyApp\ApplicationBundle\Repository\BaseRepository
    arguments: ['@csa_guzzle.client.mce']

BaseRepository:

use GuzzleHttp\Client;

class BaseRepository
{
    public function __construct(Client $client)
    {
        var_dump($client);
        echo __CLASS__;
    }
}

但后来我收到了以下错误:

  

类型错误:参数1传递给   MyApp \ ApplicationBundle \ Repository \ BaseRepository :: __ construct()必须   是一个GuzzleHttp \ Client的实例,没有给出,被称为   MyApp / src / Chameleon / DefaultBundle / Controller / DefaultController.php on   第20行

任何人都知道我能做什么?

谢谢!

2 个答案:

答案 0 :(得分:1)

要获取由服务容器管理的类,您必须使用所述容器来获取具有该标识myapp.base_repository的服务,如Twifty所说:

$this->get('myapp.base_repository');
// or more generally in classes implementing ContainerAwareInterface:
$this->container->get('myapp.base_repository');

如果您自己创建一个新实例,则必须管理所有依赖项:

// In your controller extending Symfony's Controller:
$repository = new BaseRepository();
$repository->setContainer($this->container);

同样,如果您将Guzzle客户端注入存储库,则必须从容器中检索服务或使用所有依赖项自行创建:

// $this->get() assumes you are in the controller as well
$repositoryWithClientFromServiceContainer = new BaseRepository(
    $this->get('csa_guzzle.client.mce')
);
// This obviously works everywhere
$repositoryWithNewDefaultClient = new BaseRepository(
    new GuzzleHttp\Client()
);

此外,将服务容器注入类中会违反您尝试通过首先使用服务容器实现的依赖项反转。这意味着,您应该只在存储库中添加所需的服务,而不是整个容器,而不是使您的存储库ContainerAware。就像你在第二个例子中使用Guzzle-client一样。

有些人认为控制器违反这个原则是可以的,但我个人更喜欢controller's being defined as services能够通过查看构造函数来快速查看他们所拥有的依赖关系。

作为一般规则,我会避免使用ContainerAwareInterface。

答案 1 :(得分:0)

  

同样,如果您将Guzzle客户端注入到您拥有的存储库中   要么从容器中检索服务,要么创建它   自己拥有所有依赖项:

// $this->get() assumes you are in the controller as well
$repositoryWithClientFromServiceContainer = new BaseRepository(
    $this->get('csa_guzzle.client.mce')
);
// This obviously works everywhere
$repositoryWithNewDefaultClient = new BaseRepository(
    new GuzzleHttp\Client()
);
     

此外,将服务容器注入类中会违反   您尝试使用服务容器实现的依赖项反转   首先。这意味着,而不是创建您的存储库   ContainerAware您应该只添加所需的服务   存储库,而不是整个容器。就像你在第二个例子中所做的那样   与Guzzle-client。

     

有些人认为控制人违反这一原则是可以的,   但我个人更喜欢[控制器被定义为服务] [1]   通过查看,能够快速查看他们所拥有的依赖关系   构造

     

作为一般规则,我会避免使用ContainerAwareInterface。

     

[1]:http://symfony.com/doc/current/cookbook/controller/service.html

谢谢。

所以,如果我只注入guzzleClient,那将是更好的解决方案,对吧? 如您所见,我有一些从我的BaseRepository扩展的类,他们需要guzzleClient。

但是如何为这种情况注入guzzleClient呢?如果程序员只想创建他的基本&#34; MyRep&#34;控制器中的存储库类没有任何参数。

services.yml

myapp.base_repository:
    class: MyApp\ApplicationBundle\Repository\BaseRepository
    arguments: ['@csa_guzzle.client.mce']

BaseRepository:

use GuzzleHttp\Client;
class BaseRepository
{
    private $client = null;
    public function __construct(Client $client)
    {
        var_dump($client);
        $this->client = $client;
    }

    public getClient() {
       return $this->client;
    }
}

MyRepository:

MyRep extends BaseRepository:
    use GuzzleHttp\Client;
    class BaseRepository
    {
        public function __construct()
        {
            var_dump($this->getClient());
        }
    }

谢谢!