Yii2 DI容器:两次注册相同的类,但具有不同的构造函数参数

时间:2018-12-13 10:35:01

标签: php dependency-injection yii2

在我的项目中,我使用Yii2本机依赖项注入容器,该容器在应用程序引导文件中设置。 我要实现的是两次注入相同的类,但是使用不同的构造函数参数:

Yii::$container->set(
    'common\components\ElasticSearchClient',
    [],
    [$elasticSearchServer1Params]
);

Yii::$container->set(
    'common\components\ElasticSearchClient',
    [],
    [$elasticSearchServer2Params]
);

稍后,这些弹性搜索客户端类对象应自动注入到其他类中,如下所示:

class SomeClass1
{
    /**
     * @var ElasticSearch
     */
    protected $elasticSearchClient1;

    public function __construct(\common\components\ElasticSearchClient $elasticSearchClient1) {
        $this->elasticSearchClient1 = $elasticSearchClient1;
    }
}

class SomeClass2
{
    /**
     * @var ElasticSearch
     */
    protected $elasticSearchClient2;

    public function __construct(\common\components\ElasticSearchClient $elasticSearchClient2) {
        $this->elasticSearchClient2 = $elasticSearchClient2;
    }
}

那么有可能这样做吗?我应该以某种方式使用DI容器别名吗?

1 个答案:

答案 0 :(得分:1)

您应该对依赖注入容器中的组件使用别名。例如:

将组件添加到DI容器:

Yii::$container->set(
    'component1',
    [
        'class' => '\common\components\ElasticSearchClient'
    ],
    [$elasticSearchServer1Params]    
);

从DI容器中获取组件

$component = Yii::container->get('component1');
$someObject = new SomeClass1($component);

但是解决此任务的更清晰方法是在创建SomeClass之前注册一个ElasticSearchClient组件及其配置

// add the component to the container
Yii::$container->set(
    'common\components\ElasticSearchClient',
);

// get the component from container and configure it
Yii::$container->get('common\components\ElasticSearchClient', 
                     [], 
                     [$elasticSearchServer1Params]
);
$someObject = new SomeClass1($component);

此外,您可以在DI容器中注册SomeClass1和SomeClass2,以便于创建它们。

$container->set('SomeClass1', function ($container, $params, $config) {
    $searchClient = $contaier->get('common\components\ElasticSearchClient',
                                   [], 
                                   [$elasticSearchServer1Params]
    );
    return new SomeClass1($searchClient);
});

$container->set('SomeClass2', function ($container, $params, $config) {
    $searchClient = $contaier->get('common\components\ElasticSearchClient',
                                   [], 
                                   [$elasticSearchServer2Params]
    );
    return new SomeClass2($searchClient);;
});