2

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

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

通过调用,这在我的控制器中完美运行:

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

但是,我没有看到有关如何动态地将参数实际设置为我的服务的任何信息,上面只是将字符串“环境”静态传递给类构造函数。但是我希望它传递以下值:

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

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

任何人都可以帮忙吗?

4

2 回答 2

2

依赖注入主要有两种类型。在 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 中,有一种使用标签配置在另一个服务中注册服务的方法。请参阅使用标记服务

我过去实现过这种方法,它非常好,但它很大。如果有人需要实现,我很乐意把它放在这里。

于 2015-05-25T05:49:49.130 回答
1

您可以注入kernel.environment参数:

services:
    system_info_memory:
        class:     %system_info.memory.class%
        arguments: [ %kernel.environment% ]
于 2013-06-29T13:11:48.450 回答