如何将已配置的应用程序组件注入到Model实例中?

时间:2016-09-10 13:25:11

标签: php dependency-injection yii2 yii2-basic-app

我在主题中描述了一个问题。让我解释。我使用基本的应用程序模板我有简单的模型搜索,它使用应用程序组件GoogleCustomSearch搜索Google Custom Search API。 GoogleCustomSearch必须配置Google API密钥和搜索引擎ID。我通过应用程序配置config / web.php指定Google API密钥和搜索引擎ID。我想将已配置的 GoogleCustomSearch实例注入搜索模型的实例中。是否有可能以更清洁的方式实现我的目标(下面的解决方法)?

文件:models / Search.php

namespace app\models;

use app\components\GoogleCustomSearch;
use yii\base\Model;

class Search extends Model
{
    /** @var GoogleCustomSearch */
    protected $googleCustomSearch;

    public function __construct(GoogleCustomSearch $googleCustomSearch, array $config = [])
    {
        $this->googleCustomSearch = $googleCustomSearch;
        parent::__construct($config);
    }
    ....
}

文件:components / GoogleCustomSearch.php

namespace app\components;

use yii\base\Component;
use yii\base\InvalidValueException;

class GoogleCustomSearch extends Component
{
    public $searchEngineId;
    public $apiKey;
    ...
}

我目前的解决方法

文件:config / bootstrap.php     

use app\models\Search;
use yii\di\Container;
use yii\web\Application;

\Yii::$container->set('search', function (Container $container, $params, $config) {
    $googleCustomSearch = $container->get(Application::class)->googleCustomSearch;
    array_unshift($params, $googleCustomSearch);
    return $container->get(Search::class, $params, $config);
});

文件:web / index.php     

use yii\web\Application;

....

require (__DIR__ . '/../config/bootstrap.php');
$config = require(__DIR__ . '/../config/web.php');

\Yii::$container
    ->setSingleton(Application::class, [], [$config])
    ->get(Application::class)
    ->run()
;

然后致电

/** @var Search $model */
$model = \Yii::createObject('search');

是否有更简洁的方法将已配置的组件注入对象实例?

1 个答案:

答案 0 :(得分:1)

  • 你的模特部分很好。它对如何注入依赖性及其正确的执行方式一无所知。
  • 在引导程序中,我设置GoogleCustomSearch而不是搜索模型:

    Yii :: $ container-> set(GoogleCustomSearch :: class,function(Container $ container,$ params,$ config){     返回Yii :: $ app-> googleCustomSearch; });

  • 不确定修改后的index.php的目的。