コンテナと依存関係の注入



コンテナと依存性注入(コンテナ)

依存性注入はコンテナを介して実装され、自動導入が実現できます。参照クラスの依存関係、およびクラスの依存オブジェクトの自動ロード

依存関係注入とは、コンストラクターを介したクラス依存関係の自動注入を指します:

<?php
namespace app\index\controller;

use app\index\model\User;

class Index
{
    protected $user;

    // 通过依赖注入方式,实现User实例的自动注入到当前对象中
    public function __construct(User $user)
    {
        $this->user = $user;
    }

    public function hello()
    {
        return 'Hello,' . $this->user->name . '!';
    }
}

依存関係注入のオブジェクト パラメーターのサポート複数、そして順序は関係ありません。

バインディング

依存関係が挿入されたクラスはコンテナーによって均一に管理され、ほとんどの場合、自動的にバインドされてインスタンス化されます。ただし、いつでも手動でクラスをコンテナにバインドでき (通常はサービス クラスの register メソッドで)、複数のバインド メソッドがサポートされています。

クラス識別のバインド

迅速な呼び出しのために、識別 (一意) を既存のクラス ライブラリにバインドできます。

// 绑定类库标识
$this->app->bind('cache', 'think\Cache');

またはヘルパー関数を使用します

// 绑定类库标识
bind('cache', 'think\Cache');

バインドされたクラス識別子は、(競合がない限り) 自分で定義できます。

バインディング クロージャ

クロージャをコンテナにバインドできます

bind('sayHello', function ($name) {
    return 'hello,' . $name;
});

バインディング インスタンス

クラスのインスタンスを直接バインドすることもできます

$cache = new think\Cache;
// 绑定类实例
bind('cache', $cache);

インターフェイス実装にバインド

インターフェイス クラスを使用した依存関係注入の場合、どの特定のインスタンスをシステムに伝える必要があります。インジェクションに使用するインターフェイス実装クラス。これを使用すると、特定のクラスをインターフェイスにバインドできます

// 绑定think\LoggerInterface接口实现到think\Log
bind('think\LoggerInterface','think\Log');

依存関係注入のタイプとしてインターフェイスを使用します

<?php
namespace app\index\controller;

use think\LoggerInterface;

class Index
{
    public function hello(LoggerInterface $log)
    {
    	$log->record('hello,world!');
    }	
}

バッチ バインディング決定

実際のアプリケーション開発プロセスでは、手動でバインドする必要はありません。アプリケーション ディレクトリの下に Provider.php ファイルを定義するだけで (配列を返します)、システムはクラス ライブラリを自動的にバインドします。バッチのコンテナ。中央。

return [
    'route'      => \think\Route::class,
    'session'    => \think\Session::class,
    'url'        => \think\Url::class,
];

バインディング識別子は呼び出されるときに大文字と小文字が区別されます。システムにはすでにバインディング コア共通クラス ライブラリが組み込まれているため、それらを繰り返しバインドする必要はありません。

システムの組み込み-コンテナにバインドされたクラス ライブラリに include

#think\Dbdbthink\Debugdebugthink \Envenvthink\Eventevent #think\Httphttp##think\Lang#think\Loglogthink\ミドルウェアミドルウェアthink\Requestrequestthink\Responseresponsethink\ファイルシステムファイルシステムthink\Route routethink\Sessionsessionthink\Validate 検証think\Viewview

分析

アプリ ヘルパー関数を使用して、コンテナー内でクラス分析呼び出しを行います。バインドされたクラス識別子の場合、自動的かつ迅速にインスタンス化されます

$cache = app('cache');

パラメーターを使用してインスタンス化呼び出しを行う

$cache = app('cache',['file']);

非バインド クラスの場合は、直接解析することもできます

$arrayItem = app('org\utils\ArrayItem');

呼び出しとバインディングの識別子は一貫している必要があります (大文字と小文字の区別も含む)

コンテナ 既に呼び出されたクラスは、次のメソッドを使用して再インスタンス化を強制しない限り、自動的にシングルトンを使用します。

// 每次调用都会重新实例化
$cache = app('cache', [], true);

オブジェクト化された呼び出し

アプリ ヘルパー関数を使用して、コンテナー内のオブジェクト インスタンスを取得します (依存関係の注入をサポートします)。

$app = app();
// 判断对象实例是否存在
isset($app->cache);

// 注册容器对象实例
$app->cache = think\Cache::class;

// 获取容器中的对象实例
$cache = $app->cache;

言い換えれば、どこでも app() メソッドを使用してコンテナ内の任意のクラスを呼び出すことができますが、ほとんどの場合、依存関係の注入を使用することをお勧めします。

// 调用配置类
app()->config->get('app_name');
// 调用session类
app()->session->get('user_name');

自動注入

コンテナは主に依存関係の注入に使用されます。依存関係の注入では、まずオブジェクト インスタンスがコンテナに登録されているかどうかが確認されます。登録されていない場合は、を実行すると、自動的にインスタンス化され、次に自動的に挿入されます。例:

モデル オブジェクト インスタンスをルートにバインドできます

Route::get('user/:id','index/Index/hello')
	->model('\app\index\model\User');

その後、ユーザー モデルを操作メソッドに自動的に挿入します

<?php
namespace app\index\controller;

use app\index\model\User;

class Index
{

    public function hello(User $user)
    {
        return 'Hello,'.$user->name;
    }

}

カスタマイズされたインスタンス化

コンテナー内のオブジェクトのインスタンス化はカスタマイズをサポートしています。依存関係注入が必要なオブジェクトに __make メソッド定義を追加できます。例:

If 依存関係の注入中に User モデル クラスでカスタム インスタンス化を使用する場合は、次のメソッドを使用できます。

<?php
namespace app\index\model;

use think\Model;
use think\db\Query;

class User extends Model
{
	public static function __make(Query $query)
    {
    	return (new self())->setQuery($query);
    }
}

コンテナ オブジェクトのコールバック メカニズム

コンテナ内のオブジェクトがインスタンス化された後、アノテーション関数などの関連関数を実装するために使用できるコールバック メカニズムがサポートされます。 。

解決メソッドを使用してグローバル コールバックを登録できます。

Container::getInstance()->resolving(function($instance,$container) {
    // ...
});

コールバック メソッドは 2 つのパラメータをサポートします。最初のパラメータはコンテナ オブジェクト インスタンスで、2 番目のパラメータはコンテナ インスタンス自体です。

または、コンテナ オブジェクトのコールバックを個別に登録します

Container::getInstance()->resolving(\think\Cache::class,function($instance,$container) {
    // ...
});


システム クラス ライブラリコンテナ バインディング識別子
think\Appapp
think\Cacheキャッシュ
think\Config config
think\Cookiecookie
think\Consoleコンソール
lang