PHP的高效IOC框架——CanoeDI
一個非常簡單且實用的IoC框架,相對于其他的Ioc框架有如下特點:
- 高效: 框架使用了非常實用且高效的算法,使得框架本身對應用的影響微乎其微,且框架提供了C擴展,最大限度的將性能提升到最高。
- 配置簡單: 大多數情況下幾乎不需要額外的配置
- 自動裝配: 基于PHPDocument的property屬性來自動裝配
- 懶加載: 所有被注入的變量的實例都為即用即取, 不會產生內存垃圾
- IDE友好: 因為利用的是PHP的標準規范, 兼容大部分IDE
安裝
編譯安裝,可以得到最大的效率:
$ git clone https://github.com/dustinfog/canoe-di.git
$ cd canoe-di/ext
$ phpize
$ ./configure
$ make
$ sudo make install
而后編輯php.ini
[canoe-di]
extension=canoe_di.so
composer安裝 (生產環境如果已經編譯安裝了擴展,此步驟可省略。在開發環境,PHP源碼可以讓IDE提供代碼完成提示,所以仍然推薦執行這一步):
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標注:
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(); //試一下會發生什么
Singleton
有時候,我們需要在一個非DI環境里有限的使用DI,這時候每個系統與DI容器的先借點都在調用Context::get()顯得很丑陋,框架里提供了一個更加親民的調用方式:
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"的關系。
預先定義
上面的例子都是在運行時來實現自動裝配的,但在某些時候可能需要手動預先創建一些定 義,以備后續使,框架提供了簡單的支持.
//注冊類
Canoe\DI\Context::registerDefinition('a', ClassA::class);
//注冊回調
Canoe\DI\Context::registerDefinition(
'b',
function() {
return new ClassB();
}
);
//注冊實例
Canoe\DI\Context::set('c', new ClassC());
配置
大多數時候,預先定義都是寫在配置文件里,可以用下列的方法加載配置:
\Canoe\DI\Context::loadConfig(
[
'definitions' => [ //這里是定義
ClassB::class,
],
'beans' => [ //這里可以預定義一些實際的值
'uid' => 5,
],
]);
項目地址:https://github.com/dustinfog/canoe-di
來自:http://www.cnblogs.com/dustinfog/p/6083485.html
本文由用戶 ChristinaG3 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!