Symfony服务参数

时间:2013-06-29 11:38:32

标签: php symfony dependency-injection containers

如何指定服务的参数。在Symfony文档之后,我通过将其添加到我的包中的config.yml文件中来创建自己的服务。

    system_info_memory:
        class:        "%system_info.memory.class%"
        arguments:    ['enviroment']

这在我的控制器中完美地通过调用:

$service = $this->get('system_info_memory');

但是我没有看到如何动态地将参数设置为我的服务,上面只是静态地将字符串'environment'传递给类构造函数。但是,我希望传递的值为:

$this->container->get( 'kernel' )->getEnvironment()

从容器中获取类的实例之前。

有人可以帮忙吗?

2 个答案:

答案 0 :(得分:1)

主要有两种类型的依赖注入。在Symfony中,我们还有一个额外的方法,我在这里解释了所有这些。

1-构造函数注入

此方法要求客户端在构造函数中提供参数 Symfony将通过在配置文件中定义服务参数来为您完成的服务。

saman.search:
    class: Saman\SearchBundle\Services\SearchService
    arguments: 
      - @translator
      - @doctrine.orm.default_entity_manager
      - %search_service_parameters%

在您的服务类中,您有:

<?php

namespace Library\Services;

use Doctrine\ORM\EntityManager;
use Symfony\Bundle\FrameworkBundle\Translation\Translator;

class SearchService
{
    /**
     * Translator services
     * 
     * @var TranslatorService $translatorService
     */
    protected $translatorService;

    /**
     *
     * @var EntityManager $em
     */
    protected $em;

    /**
     * Client side parameters
     * 
     * @var array
     */
    protected $parameters;

    public function __construct(
        TranslatorService $translatorService, 
        EntityManager $em,
        array $parameters = array()
        )
    {
        $this->translatorService = $translatorService;
        $this->em = $em;
        $this->parameters = $parameters;
    }

    public function doSomething()
    {
        return $this->translatorService->trans('app.text.hello');  
    }
}
?>

2-塞特尔注射

此方法要求您的服务为每个依赖项提供setter方法。 当您想要使用该服务时,您可以动态设置依赖关系。 这使您可以随时自由设置依赖。

saman.search:
    class: Saman\SearchBundle\Services\SearchService
    arguments: 
      - @translator
      - @doctrine.orm.default_entity_manager
      - %search_service_parameters%

saman.a:
    class: Saman\SearchBundle\Services\A
    arguments: ~

在您的服务中,您有:

<?php

namespace Library\Services;

use Doctrine\ORM\EntityManager;
use Symfony\Bundle\FrameworkBundle\Translation\Translator;
use Library\Services\A;

class SearchService
{
    /**
     * Translator services
     * 
     * @var TranslatorService $translatorService
     */
    protected $translatorService;

    /**
     *
     * @var EntityManager $em
     */
    protected $em;

    /**
     * Service A
     * @var A $a
     */
    protected $a;

    /**
     * Client side parameters
     * 
     * @var array
     */
    protected $parameters;

    public function __construct(
        TranslatorService $translatorService, 
        EntityManager $em,
        array $parameters = array()
        )
    {
        $this->translatorService = $translatorService;
        $this->em = $em;
        $this->parameters = $parameters;
    }

    public function setServiceA(A $a)
    {
        $this->a = $a;

        return $this;
    }

    public function doSomethingNeedServiceA()
    {
        return $this->getServiceA()->doSomethingInA();  
    }

    private function getServiceA()
    {
        if (null === $this->a) {
            throw new \LogicException("You should set service A first");  
        }

        return $this->a;
    }
}
?>

使用接口

也可以改善这一点
<?php

namespace Library\Services;

use Doctrine\ORM\EntityManager;
use Symfony\Bundle\FrameworkBundle\Translation\Translator;
use Library\Interfaces\A;

class SearchService
{
    /**
     * Translator services
     * 
     * @var TranslatorService $translatorService
     */
    protected $translatorService;

    /**
     *
     * @var EntityManager $em
     */
    protected $em;

    /**
     * Interfaces A
     * @var A $a
     */
    protected $a;

    /**
     * Client side parameters
     * 
     * @var array
     */
    protected $parameters;

    public function __construct(
        TranslatorService $translatorService, 
        EntityManager $em,
        array $parameters = array()
        )
    {
        $this->translatorService = $translatorService;
        $this->em = $em;
        $this->parameters = $parameters;
    }

    public function setServiceA(A $a)
    {
        $this->a = $a;

        return $this; 
    }

    public function doSomethingNeedServiceA()
    {
        return $this->getServiceA()->doSomethingInA();  
    }

    private function getServiceA()
    {
        if (null === $this->a) {
            throw new \LogicException("You should set a service that implement A interfaces");  
        }

        return $this->a;
    }
}
?>

和您的界面

<?php

namespace Library\Interfaces;

interface A
{
    public function doSomethingInA();
}
?>

然后,当您想要使用此服务时,您应该

$aService = $this->get('saman.a');
$searchService = $this->get('saman.search');

$searchService->setServiceA($aService)
    ->doSomethingNeedServiceA();

3标记服务

在Symfony中,有一种方法可以在另一个服务中注册服务,使用配置标记Working with Tagged Services

我已经实现了这种方法,它非常好,但它很大。如果有人需要实施,我很乐意听到。

答案 1 :(得分:0)

您可以注入kernel.environment参数:

services:
    system_info_memory:
        class:     %system_info.memory.class%
        arguments: [ %kernel.environment% ]