簡(jiǎn)單的服務(wù)容器
一個(gè)簡(jiǎn)單的 php 5.3
依賴注入容器梯捕。
項(xiàng)目地址:https://github.com/godruoyi/easy-container
Why
目前比較流行的 PHP
容器:
Pimple
是一個(gè)簡(jiǎn)單優(yōu)秀的 php 5.3
容器,也是目前用得最多的服務(wù)容器张惹,在 packagist 的安裝量也達(dá)到 1000 w+
。但是 Pimple
只是一個(gè)簡(jiǎn)單的服務(wù)容器蚪缀,不支持很多特性如:
class Cache
{
public function __construct(Config $config){}
}
class Config
{
}
// 不支持
$cache = $container->make('Cache');
Pimple 不支持自動(dòng)注入依賴參數(shù)誓竿,當(dāng)你需要的對(duì)象依賴其他對(duì)象時(shí),你只能依次實(shí)例化所需參數(shù)客年。
Laravel Container
是目前功能最全的服務(wù)容器了,支持的功能也比較全面漠吻,包括自動(dòng)注入、賴加載司恳、別名途乃、TAG等。但是官方不推薦在非 laravel
項(xiàng)目中使用該組件扔傅。
如果你有留意該組件下的
composer.json
文件耍共,你會(huì)發(fā)現(xiàn)他依賴 illuminate/contracts 組件。(參見)
基于此猎塞,誕生了 easy-container试读,該項(xiàng)目代碼大部分依賴于 Laravel Container :smile:。你可以像使用 Laravel Container
容器般來使用它荠耽。
安裝
composer require godruoyi/easy-container
使用
你可以前往 Laravel-china 獲取更多關(guān)于 容器使用 的幫助钩骇。
初始化容器
$app = new Godruoyi\Container\Container;
以下文檔支持來自 laravel-china,轉(zhuǎn)載請(qǐng)注明出處铝量。
簡(jiǎn)單綁定
可以通過 bind
方法注冊(cè)綁定倘屹,傳遞我們想要注冊(cè)的類或接口名稱再返回類的實(shí)例的 Closure
:
$app->bind('HelpSpot\API', function ($app) {
return new HelpSpot\API($app->make('HttpClient'));
});
注意,所有匿名函數(shù)都接受服務(wù)容器實(shí)例作為參數(shù)慢叨。
綁定一個(gè)單例
singleton
方法將類或接口綁定到只能解析一次的容器中纽匙。綁定的單例被解析后,相同的對(duì)象實(shí)例會(huì)在隨后的調(diào)用中返回到容器中:
$app->singleton('HelpSpot\API', function ($app) {
return new HelpSpot\API($app->make('HttpClient'));
});
每次調(diào)用
$app['HelpSpot\API']
都將返回統(tǒng)一對(duì)象拍谐。
綁定實(shí)例
你也可以使用 instance
方法將現(xiàn)有對(duì)象實(shí)例綁定到容器中烛缔。給定的實(shí)例會(huì)始終在隨后的調(diào)用中返回到容器中:
$api = new HelpSpot\API(new HttpClient);
$app->instance('HelpSpot\API', $api);
綁定接口到實(shí)現(xiàn)
服務(wù)容器有一個(gè)強(qiáng)大的功能馏段,就是將接口綁定到給定實(shí)現(xiàn)。例如践瓷,如果我們有一個(gè) EventPusher
接口和一個(gè) RedisEventPusher
實(shí)現(xiàn)院喜。編寫完接口的 RedisEventPusher
實(shí)現(xiàn)后,我們就可以在服務(wù)容器中注冊(cè)它当窗,像這樣:
$app->bind(
'App\Contracts\EventPusher',
'App\Services\RedisEventPusher'
);
這么做相當(dāng)于告訴容器:當(dāng)一個(gè)類需要實(shí)現(xiàn) EventPusher
時(shí)够坐,應(yīng)該注入 RedisEventPusher
。現(xiàn)在我們就可以在構(gòu)造函數(shù)或者任何其他通過服務(wù)容器注入依賴項(xiàng)的地方使用類型提示注入 EventPusher
接口:
use App\Contracts\EventPusher;
/**
* 創(chuàng)建一個(gè)新的類實(shí)例崖面,此處將注入 App\Services\RedisEventPusher 的實(shí)例元咙。
*
* @param EventPusher $pusher
* @return void
*/
public function __construct(EventPusher $pusher)
{
$this->pusher = $pusher;
}
解析
make
方法
你可以使用 make
方法將容器中的類實(shí)例解析出來 (無(wú)論該對(duì)象需要什么類型的參數(shù))。make
方法接受要解析的類或接口的名稱:
$api = $app->make('HelpSpot\API');
mark
方法是我認(rèn)為最重要的方法巫员,你可以簡(jiǎn)單地使用「類型提示」的方式在由容器解析的類的構(gòu)造函數(shù)中添加依賴項(xiàng)庶香,容器將自動(dòng)解析你所需要的一切參數(shù)。
// 自動(dòng)解析UserController構(gòu)造函數(shù)所需的依賴
$userController = $app->make(UserController::class);
class UserController
{
public function __construct(UserRepository $users, HttpClient $client, $other = 'default')
{
}
}
PSR-11
Laravel 的服務(wù)容器實(shí)現(xiàn)了 PSR-11 接口简识。因此赶掖,你可以對(duì) PSR-11容器接口類型提示來獲取 Laravel 容器的實(shí)例:
use Psr\Container\ContainerInterface;
$service = $app->get('Service');
LISTEN
MIT