一個很是簡單且實用的IoC框架,相對於其餘的Ioc框架有以下特色:php
編譯安裝,能夠獲得最大的效率:html
$ git clone https://github.com/dustinfog/canoe-di.git $ cd canoe-di/ext $ phpize $ ./configure $ make $ sudo make install
然後編輯php.inigit
[canoe-di] extension=canoe_di.so
composer安裝 (生產環境若是已經編譯安裝了擴展,此步驟可省略。在開發環境,PHP源碼可讓IDE提供代碼完成提示,因此仍然推薦執行這一步):github
composer require dustinfog/canoe-di
class ClassA { } //DI容器在處理類型時,會在第一次遇到的時候實例化,而且在之後使用中以單例的方式使用。 $a = \Canoe\DI\Context::get(ClassA::class);
class ClassC { } use \Canoe\DI\DITrait; use \Canoe\DI\Context; /** * @property ClassC $c */ class ClassA { //須要引入一個trait,用以處理$c的獲取 use DITrait; public function test() { //這裏能夠直接使用 print_r($this->c); } } $a = Context::get(ClassA::class); $a->test(); //試一下會發生什麼
uses能夠指定屬性使用的類或者容器裏的實例算法
interface InterfaceC { public function sayHello(); } class ClassWorld implements InterfaceC { public function sayHello() { echo "hello, world!\n"; } } class ClassC implements InterfaceC { private $name; public function __construct($name) { $this->name = $name; } public function sayHello() { echo "hello, $name!\n"; } } use \Canoe\DI\DITrait; use \Canoe\DI\Context; /** * @property InterfaceC $c1 {@uses ClassWorld} //使用類名 * @property InterfaceC $c2 {@uses c2} //使用容器內的ID */ class ClassA { //須要引入一個trait,用以處理$c的獲取 use DITrait; public function test() { print_r($this->c1); print_r($this->c2); } } Context::set("c2", new ClassC("Bob")); // 更好的選擇:Context::registerDefinition("c2", function(){new ClassC("Bob")}) $a = Context::get(ClassA::class); $a->test(); //試一下會發生什麼
有時候,咱們須要在一個非DI環境裏有限的使用DI,這時候每一個系統與DI容器的先借點都在調用Context::get()顯得很醜陋,框架裏提供了一個更加親民的調用方式:shell
use \Canoe\DI\SingletonTrait; class ClassA { use SingletonTrait; } $a = ClassA::getInstance(); // 與Context::get(ClassA::class)等價,但隱藏了Context調用。 $a = ClassA::getInstance("a1"); // 與Context::get("a1")等價,但作了進一步的類型檢查,即a1取到的實例與ClassA必須有"is a"的關係。
上面的例子都是在運行時來實現自動裝配的,但在某些時候可能須要手動預先建立一些定 義,以備後續使,框架提供了簡單的支持.bash
//註冊類 Canoe\DI\Context::registerDefinition('a', ClassA::class); //註冊回調 Canoe\DI\Context::registerDefinition( 'b', function() { return new ClassB(); } ); //註冊實例 Canoe\DI\Context::set('c', new ClassC());
大多數時候,預先定義都是寫在配置文件裏,能夠用下列的方法加載配置:composer
\Canoe\DI\Context::loadConfig( [ 'definitions' => [ //這裏是定義 ClassB::class, ], 'beans' => [ //這裏能夠預約義一些實際的值 'uid' => 5, ], ]);
項目地址:https://github.com/dustinfog/canoe-di