PHP的高效IOC框架——CanoeDI

CanoeDI是一款专为PHP设计的高效IOC框架,它以极简配置、自动装配、懒加载等特点著称,同时兼容多种IDE,提供C扩展以最大化性能。通过基于PHPDocument的property属性进行自动装配,简化了依赖注入过程。

PHP的高效IOC框架——CanoeDI

一个非常简单且实用的IoC框架,相对于其他的Ioc框架有如下特点:

  1. 高效: 框架使用了非常实用且高效的算法,使得框架本身对应用的影响微乎其微,且框架提供了C扩展,最大限度的将性能提升到最高。
  2. 配置简单: 大多数情况下几乎不需要额外的配置
  3. 自动装配: 基于PHPDocument的property属性来自动装配
  4. 懒加载: 所有被注入的变量的实例都为即用即取, 不会产生内存垃圾
  5. IDE友好: 因为利用的是PHP的标准规范, 兼容大部分IDE

安装

编译安装,可以得到最大的效率:

1
2
3
4
5
6
$ git clone https: //github .com /dustinfog/canoe-di .git
cd  canoe-di /ext
$ phpize
$ . /configure
make
sudo  make  install

 

而后编辑php.ini

1
2
[canoe-di]
extension=canoe_di.so

 composer安装 (生产环境如果已经编译安装了扩展,此步骤可省略。在开发环境,PHP源码可以让IDE提供代码完成提示,所以仍然推荐执行这一步):

1
composer require dustinfog /canoe-di

 

使用

获取实例

1
2
3
4
5
class  ClassA
{
}
//DI容器在处理类型时,会在第一次遇到的时候实例化,并且在以后使用中以单例的方式使用。
$a  = \Canoe\DI\Context::get(ClassA:: class );

 

基于标注的装配

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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可以指定属性使用的类或者容器里的实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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()显得很丑陋,框架里提供了一个更加亲民的调用方式:

1
2
3
4
5
6
7
8
9
10
11
12
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"的关系。

 

预先定义

上面的例子都是在运行时来实现自动装配的,但在某些时候可能需要手动预先创建一些定 义,以备后续使,框架提供了简单的支持.

1
2
3
4
5
6
7
8
9
10
11
//注册类
Canoe\DI\Context::registerDefinition( 'a' , ClassA:: class );
//注册回调
Canoe\DI\Context::registerDefinition(
     'b' ,
     function () {
         return  new  ClassB();
     }
);
//注册实例
Canoe\DI\Context::set( 'c' new  ClassC());

 

配置

大多数时候,预先定义都是写在配置文件里,可以用下列的方法加载配置:

1
2
3
4
5
6
7
8
9
\Canoe\DI\Context::loadConfig(
[
     'definitions'  => [  //这里是定义
         ClassB:: class ,
     ],
     'beans'  => [  //这里可以预定义一些实际的值
         'uid'  => 5,
     ],
]);

 

转发 项目地址:https://github.com/dustinfog/canoe-di

转载于:https://www.cnblogs.com/gh0408/p/6132235.html

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值