Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Dependency injection 如何在Yii2配置中注入类依赖关系?_Dependency Injection_Configuration_Yii2_Config - Fatal编程技术网

Dependency injection 如何在Yii2配置中注入类依赖关系?

Dependency injection 如何在Yii2配置中注入类依赖关系?,dependency-injection,configuration,yii2,config,Dependency Injection,Configuration,Yii2,Config,我在学Yii2。有一种情况我还没有用谷歌搜索到答案 我在config/console.php的$config['components']数组中注册了一个名为scraper的组件 这个scraper类有一个公共属性$\u client,它是一个Goutte\client类 我尝试使用以下方法设置scraper组件,但它不起作用,Yii2没有将$\u client实例化为Goutte\client对象 $config = [ 'scraper' => [ 'class'

我在学Yii2。有一种情况我还没有用谷歌搜索到答案

我在
config/console.php
$config['components']
数组中注册了一个名为
scraper
的组件

这个
scraper
类有一个公共属性
$\u client
,它是一个
Goutte\client

我尝试使用以下方法设置
scraper
组件,但它不起作用,Yii2没有将
$\u client
实例化为
Goutte\client
对象

$config = [
   'scraper' => [
        'class' => 'app\models\Scraper',
        '_pageSize' => 10,
        '_client' =>  [  //not working. can not instantiate this property as an object
            'class' => 'Goutte\Client'
        ],
   ],
   //... 
]

问题:在配置中注入依赖项的工作方式是什么?

Yii2不会实例化配置数组中第一级以外的对象。换句话说,
scraper
将被实例化为一个对象,但它的属性
\u client
将被实例化为一个数组
['class'=>'Goutte\client']

您应该自己实现这个逻辑:

class Service extends Component
{
    private $_client = null;

    public $clientClass;

    public function getClient()
    {
        if (null !== $this->_client) {
            return $this->_client;
        }

        $this->_client = new $clientClass;

        return $this->_client;
    }
}
或者,您可以将
Goutte\Client
注册为一个单独的组件,然后Yii将正确地实例化它

更新: 为了澄清,通过
yii\base\Configurable
接口从配置中实例化对象,该接口在
yii\base\Object
类中实现。最终,此实现执行
Yii::configure

public static function configure($object, $properties)
{
    foreach ($properties as $name => $value) {
        $object->$name = $value;
    }

    return $object;
}

如您所见,所有属性都将被分配各自的值,因此
\u client
将成为一个数组,而不是一个对象。

发现了另一种方法:可以使用类名或对象初始化类的属性。要使其按预期工作,方法将被覆盖:

/**
 * {@inheritdoc}
 */
public function init()
{
    parent::init();

    foreach ($this->targets as $name => $target) {
        if (!$target instanceof Target) {
            $this->targets[$name] = Yii::createObject($target);
        }
    }
}
这允许对日志组件进行如下配置/初始化:

'log' => [
    'class' => 'yii\log\Dispatcher',
    'targets' => [
        [
            'class' => 'yii\log\FileTarget',
        ],
    ],
],
注意:这里的目标是一个数组。但是它也可以通过单个类/对象来完成

因此,在您的情况下,这应该是一个解决方案:

namespace app\models;

class Scraper extends ActiveRecord // or extends from anything that actually implements yii\base\Configurable
{
    public $_client;

    /**
     * {@inheritdoc}
     */
    public function init()
    {
        parent::init();

        if (!$this->_client instanceof Goutte\Client) {
            $this->_client = Yii::createObject($this->_client);
        }
    }
}

顺便说一句:变量名中的下划线前缀通常用于私有属性。

刮板是从模型派生的吗?
\u客户
是公共会员吗?Goutte\Client是完全限定的类名(不是app\Goutte\Client)?Goutte \客户端构造函数没有参数?Scraper是从
组件
派生的,
$\u客户端
是公共成员。当我在
Scraper
class的init()函数中初始化$\u客户机时,所有其他公共基元类型属性都在这个配置文件中设置,它工作正常。如果我在Scraper函数中
var\u dump($this->\u client)
,它会显示
$this-\u client
是数组(1){[“class”]=>string(13)“Goutte\client”}的数组。
Goutte\client
是完全限定的类名,它不需要参数。我可以在Scraper类中通过
使用Goutte\Client
导入这个类。您能提供更多的代码(类、名称空间、名称空间用法、配置等)吗?在$config中,我看不到
组件
键。我对配置没有太多经验,因此不确定是否可以帮助您。@robsch,是的,我跳过了此代码段的
组件
部分,原因是,除此
$\u client
属性外,其他所有属性都实例化得很好,所以我只想强调这一部分。谢谢你试着帮我:)这有记录吗?我补充了一些澄清。