一个很是简单且实用的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