컨테이너 및 종속성 주입
컨테이너와 종속성 주입(컨테이너)
종속성 주입은 컨테이너를 통해 구현되는데, 이는 참조된 클래스를 자동으로 도입하고 클래스의 종속 개체를 자동으로 로드할 수 있습니다.
종속성 주입 종속성을 의미합니다. 클래스의 클래스는 생성자를 통해 자동으로 주입됩니다.
<?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 . '!'; } }
종속성 주입의 객체 매개변수는 여러 객체를 지원하며 순서는 이와 관련이 없습니다.
Binding
종속성이 주입된 클래스는 컨테이너에 의해 균일하게 관리되며 대부분의 경우 자동으로 바인딩되고 인스턴스화됩니다. 그러나 언제든지 클래스를 컨테이너에 수동으로 바인딩할 수 있으며(일반적으로 서비스 클래스의 등록 메서드에서) 여러 바인딩 메서드가 지원됩니다.
클래스 식별자 바인딩
빠른 호출을 위해 식별자(고유)를 기존 클래스 라이브러리에 바인딩할 수 있습니다.
// 绑定类库标识 $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!'); } }
일괄 바인딩
실제 애플리케이션 개발 프로세스에서는 수동 바인딩이 필요하지 않습니다. 애플리케이션 디렉터리 아래에 공급자.php 파일을 정의하기만 하면(배열 반환) 시스템이 클래스 라이브러리를 일괄적으로 컨테이너에 자동으로 바인딩합니다.
return [ 'route' => \think\Route::class, 'session' => \think\Session::class, 'url' => \think\Url::class, ];
바인딩 식별자는 호출 시 대소문자를 구분합니다. 시스템에는 핵심 공통 클래스 라이브러리의 바인딩이 내장되어 있으므로 이를 반복적으로 바인딩할 필요가 없습니다.
컨테이너에 바인딩된 시스템의 내장 클래스 라이브러리는 다음과 같습니다.
시스템 클래스 라이브러리 | 컨테이너 바인딩 ID |
---|---|
thinkApp | app |
thinkCache | cache |
thinkConfig | config |
thinkCookie | cookie |
thinkConsole | console |
thinkDb | db |
thinkDebug | debug |
thinkEnv | env |
thinkEvent | event |
thinkH ttp | http |
thinkLang | lang |
thinkLog | log |
thinkMiddleware | middleware |
thinkRequest | request |
thinkResponse | 응답 |
thinkFile 시스템 | filesystem |
thinkRoute | route |
thinkSession | session |
thinkValidate | validate |
thinkView | view |
파싱
앱 도우미 기능을 사용하여 컨테이너에서 클래스 구문 분석 호출을 수행하세요. 바인딩된 클래스 식별자의 경우 자동으로 빠르게 인스턴스화됩니다.
$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 메서드 정의(예:
사용자 모델 클래스가 종속성 주입 중에 사용자 정의 인스턴스화를 사용하도록 하려면 다음 메서드를 사용할 수 있습니다.)
<?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) { // ... });
콜백 메서드는 두 개의 매개변수를 지원하며 첫 번째 매개변수는 컨테이너 개체 인스턴스이고 두 번째 매개변수는 컨테이너 인스턴스 자체입니다.
또는 특정 컨테이너 객체에 대한 콜백을 별도로 등록
Container::getInstance()->resolving(\think\Cache::class,function($instance,$container) { // ... });