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

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

PHP的高效IOC框架——CanoeDI的更多相关文章

  1. 国人编写的开源 .net Ioc 框架——My.Ioc 简介

    My.Ioc 是作者开发的一款开源 IoC/DI 框架,下载地址在此处.它具有下面一些特点: 高效 在实现手段上,My.Ioc 通过使用泛型.缓存.动态生成代码.延迟注册.尽量使用抽象类而非接口等方式 ...

  2. 解读 IoC 框架 InversifyJS

    原文链接 InversityJS 是一个 IoC 框架.IoC(Inversion of Control) 包括依赖注入(Dependency Injection) 和依赖查询(Dependency ...

  3. 使用Microsoft的IoC框架:Unity来对.NET应用进行解耦

    1.IoC/DI简介 IoC 即 Inversion of Control,DI 即 Dependency Injection,前一个中文含义为控制反转,后一个译为依赖注入,可以理解成一种编程模式,详 ...

  4. IOC框架

    一. IOC理论的背景 我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑. 图1:软件系统中耦合的对象 如果我们打开机 ...

  5. 转:IOC框架

    CSND上看了王泽滨的博客关于IOC的,觉得说的很透彻,地址为:http://blog.csdn.net/wanghao72214/article/details/3969594 1 IoC理论的背景 ...

  6. 各大主流.Net的IOC框架性能测试比较

    Autofac下载地址:http://code.google.com/p/autofac/ Castle Windsor下载地址:http://sourceforge.net/projects/cas ...

  7. Android 进阶 Android 中的 IOC 框架 【ViewInject】 (下)

    上一篇博客我们已经带大家简单的吹了一下IoC,实现了Activity中View的布局以及控件的注入,如果你不了解,请参考:Android 进阶 教你打造 Android 中的 IOC 框架 [View ...

  8. Android 进阶Android 中的 IOC 框架 【ViewInject】 (上)

    1.概述 首先我们来吹吹牛,什么叫IoC,控制反转(Inversion of Control,英文缩写为IoC),什么意思呢? 就是你一个类里面需要用到很多个成员变量,传统的写法,你要用这些成员变量, ...

  9. .NET领域最为流行的IOC框架之一Autofac

    一.前言 Autofac是.NET领域最为流行的IOC框架之一,微软的Orchad开源程序使用的就是Autofac,Nopcommerce开源程序也是用的Autofac. Orchad和Nopcomm ...

随机推荐

  1. 设计模式(二)The Observer Pattern 观察者模式

    问题引入 生成一个公告板显示当时的天气状况,当天气状况发生改变的时候公告板能够实时的更新. 模式定义 定义对象之间的一对多的依赖.当一个对象改变状态时,它的全部依赖者都会自己主动收到通知并自己主动更新 ...

  2. 10 个十分难得的 javascript 开发经验

    Javascript 的很多扩展的特性是的它变得更加的犀利, 同时也给予程序员机会创建更漂亮并且更让用户喜欢的网站. 尽管很多的开发人员都乐于颂扬 javascript,但是仍旧有人看到它的阴暗面. ...

  3. Selenium+Python浏览器调用:Firefox

    如何查看python selenium的API python -m pydoc -p  4567 说明: python -m pydoc表示打开pydoc模块,pydoc是查看python文档的首选工 ...

  4. 如何恢复Initial commit之前的源文件

    在github新建了一个空的库,然后到本地文件夹下,git init了一下,将remote和本地的关联起来了,然后git pull了一下,本地的项目源码全没了,用以下命令可以帮你恢复 git refl ...

  5. GitHub 优秀的项目地址

    Type LibDescription   LibLocation Android SlidingMenu   https://github.com/jfeinstein10/SlidingMenu ...

  6. windows 2008R2系统程序运行提示无法定位程序输入点ucrtbase.terminate

    1.用python写了个脚本,打成exe程序,在一些机器上正常运行,再另外一些机器上运行提示 无法定位程序输入点ucrtbase.terminate 应该是缺少库文件支持 2.网上搜了下.https: ...

  7. linux命令(及解压tar.gz文件)

    https://wenku.baidu.com/view/f5805017866fb84ae45c8df3.html 1.压缩命令: 命令格式:tar  -zcvf   压缩文件名.tar.gz   ...

  8. android 解决输入法键盘遮盖布局问题

    /**     * @param root 最外层布局,需要调整的布局     * @param scrollToView 被键盘遮挡的scrollToView,滚动root,使scrollToVie ...

  9. 高速入门:十分钟学会Python

    初试牛刀 如果你希望学习Python这门语言.却苦于找不到一个简短而全面的新手教程.那么本教程将花费十分钟的时间带你走入Python的大门.本文的内容介于教程(Toturial)和速查手冊(Cheat ...

  10. 《C++ Primer Plus》10.2 抽象和类 学习笔记

    10.2.1 类型是什么基本类型完成了下面的三项工作:* 决定数据对象需要的内存数量:* 决定如何解释内存中的位(long和float在内存中占用的位数相同,但是将它们转换为数值的方法不同):* 决定 ...