摘要:比如下面是的入口文件已去掉注釋首先看,其中是的一個實例,而類繼承自,所以實際上就是一個。標記有些時候,可能需要解析某個分類下的所有綁定。解析方法數組方法解析被標記綁定解析事件每當服務容器解析一個對象時就會觸發事件。
什么是Service Container
The Laravel service container is a powerful tool for managing class dependencies and performing dependency injection.
從Laravel官方文檔對于Service Container的解釋可以看出,它的作用就是幫助我們管理和進行依賴注入的。
為什么要用Service Container在《嘮嘮依賴注入》中,我們看到使用依賴注入可以極大的降低代碼的耦合度,但是也帶來了一個缺點,就是需要自己管理注入的對象。
如果一個組件有很多依賴,我們需要創建多個參數的setter方法??來傳遞依賴關系,或者建立一個多個參數的構造函數來傳遞它們,另外在使用組件前還要每次都創建依賴,這讓我們的代碼像這樣不易維護。
所以為依賴實例提供一個容器(Service Container),就是一個實用而且優雅的方法。
比如下面是laravel的入口文件(已去掉注釋):
// public/index.php make(IlluminateContractsHttpKernel::class); $response = $kernel->handle( $request = IlluminateHttpRequest::capture() ); $response->send(); $kernel->terminate($request, $response);
// bootstrap/app.php singleton( IlluminateContractsHttpKernel::class, AppHttpKernel::class ); $app->singleton( IlluminateContractsConsoleKernel::class, AppConsoleKernel::class ); $app->singleton( IlluminateContractsDebugExceptionHandler::class, AppExceptionsHandler::class ); return $app;
首先看bootstrap/app.php,其中$app是IlluminateFoundationApplication的一個實例,而IlluminateFoundationApplication類繼承自Container,所以$app實際上就是一個Service Container。
然后下面的三個singleton方法定義了當依賴IlluminateContractsHttpKernel、IlluminateContractsConsoleKernel、IlluminateContractsDebugExceptionHandler這三個接口時,注入哪個類的單例。
然后看public/index.php,其中的make方法實際上就是用Service Container來new一個IlluminateContractsHttpKernel實例,跟普通new的區別就是會把他的依賴自動注入進去。
是不是很簡潔?
其實不單是Laravel,像Yii2、Phalcon等框架都通過實現容器來管理依賴注入。
如何使用Service Container既然是一個容器,無非就是兩個事,往里放東西和往外取東西,對應到Service Container就是綁定(Binding)和解析(Resolving)。
獲得容器在Laravel的Service Provider中,可以通過$this->app獲取容器,除此之外,還可以使用app()來獲取容器。
如果在Laravel外使用Service Container,直接new一個IlluminateContainerContainer就可以獲得容器了。
以下都用$container代表獲取到的容器。
綁定綁定返回接口的實例
//使用閉包 $container->bind("BarInterface", function(){ return new Bar(); }); //或者使用字符串 $container->bind("FooInterface", "Foo");
綁定單例
singletion 方法綁定一個只會被解析一次的類或接口至容器中,且后面的調用都會從容器中返回相同的實例:
$container->singleton("BarInterface", function(){ return new Bar(); });
綁定實例
你也可以使用 instance 方法,綁定一個已經存在的對象實例至容器中。后面的調用都會從容器中返回指定的實例:
$bar = new Bar(); $bar->setSomething(new Something); $container->instance("Bar", $bar);
情境綁定
有時候,你可能有兩個類使用到相同接口,但你希望每個類都能注入不同實現。
$container->when("Man") ->needs("PartnerInterface") ->give("Woman"); $container->when("Woman") ->needs("PartnerInterface") ->give("Man");
標記
有些時候,可能需要解析某個「分類」下的所有綁定。
$container->bind("Father", function () { // }); $container->bind("Mother", function () { // }); $container->bind("Daughter", function () { // }); $container->bind("Son", function () { // }); $container->tag(["Father", "Mother", "Daughter", "Son"], "familyMembers"); $container->bind("Family", function ($container) { return new Family($container->tagged("familyMembers")); });解析
make方法
$foo = $container->make("Foo");
數組方法
$bar = $container["Bar"];
解析被標記綁定
$familyMembers = $container->tagged("familyMembers"); foreach ($familyMembers as $individual) { $individual->doSomething(); }解析事件
每當服務容器解析一個對象時就會觸發事件。你可以使用 resolving 方法監聽這個事件。
$container->resolving(function ($object, $container) { // 當容器解析任何類型的對象時會被調用... }); $container->resolving("Foo", function (Foo $foo, $container) { // 當容器解析「Foo」類型的對象時會被調用... });
博客地址:http://haitian299.github.io/2016/05/17/laravel-service-container/
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/21566.html
摘要:實際上的綁定主要有三種方式且只是一種的,這些已經在學習筆記之實例化源碼解析聊過,其實現方法并不復雜。從以上源碼發現的反射是個很好用的技術,這里給出個,看下能干些啥打印結果太長了,就不粘貼了。 說明:本文主要學習Laravel中Container的源碼,主要學習Container的綁定和解析過程,和解析過程中的依賴解決。分享自己的研究心得,希望對別人有所幫助。實際上Container的綁...
摘要:說明本文主要學習容器的實例化過程,主要包括等四個過程。看下的源碼如果是數組,抽取別名并且注冊到中,上文已經討論實際上就是的。 說明:本文主要學習Laravel容器的實例化過程,主要包括Register Base Bindings, Register Base Service Providers , Register Core Container Aliases and Set the ...
摘要:上文書,創建對象需要先創建對象。創建對象的雜活是嵌入在中的。對象使用來管理依賴關系非常好,但不是必須的。很容易實現,但手工維護各種亂七八糟的對象還是很麻煩。所有文章均已收錄至項目。 本文翻譯自 Symfony 作者 Fabien Potencier 的 《Dependency Injection in general and the implementation of a Depend...
摘要:現在我們就可以在構造函數或者任何其他通過服務容器注入依賴項的地方使用類型提示注入接口創建一個新的類實例,此處將注入的實例。自動解析構造函數所需的依賴的服務容器實現了接口。 簡單的服務容器 一個簡單的 php 5.3 依賴注入容器。 項目地址:https://github.com/godruoyi/easy-container Why 目前比較流行的 PHP 容器: Pimple La...
摘要:用匿名函數的好處在于,這個服務綁定到容器以后,并不會立即產生服務最終的對象,只有在這個服務解析的時候,匿名函數才會執行,此時才會產生這個服務對應的服務實例。 前言 ? 老實說,第一次老大讓我看laravel框架手冊的那天早上,我是很絕望的,因為真的沒接觸過,對我這種渣渣來說,laravel的入門門檻確實有點高了,但還是得硬著頭皮看下去(雖然到現在我還有很多沒看懂,也沒用過)。? 后面慢...
閱讀 2125·2019-08-29 16:53
閱讀 2700·2019-08-29 16:07
閱讀 2043·2019-08-29 13:13
閱讀 3268·2019-08-26 13:57
閱讀 1332·2019-08-26 13:31
閱讀 2434·2019-08-26 13:22
閱讀 1222·2019-08-26 11:43
閱讀 2085·2019-08-23 17:14