从百草园到三味书屋 (二)IoC 容器
IOC 容器#
laravel 核心:IOC 容器
作用: 容器使得框架各个组件能很好的在一起工作。
IOC 基本用法#
在 《从百草园到三味书屋 (一)依赖注入》 中,我们定义了 BillerInterface 和 BillingNotifierInterface 接口。
//假设我们使用了Stripe来进行支付操作。我们可以将Stripe的支付实现绑定到容器里,就像这样
App::bind('BillerInterface', function()
{
return new StripeBiller(App::make('BillingNotifierInterface'));
});
//注意在我们处理BillingInterface时,我们额外需要一个BillingNotifierInterface的实现,也就是再来一个bind:
App::bind('BillingNotifierInterface', function()
{
return new EmailBillingNotifier;//可方便切换账单通知接口的具体实现类
});
//一旦我们使用了容器,切换接口的实现就是一行代码的事儿。
class UserController extends BaseController{
public function __construct(BillerInterface $biller)
{
$this->biller = $biller;
}
}
//想在应用中只实例化某类一次?没问题,使用singleton方法吧:
App::singleton('BillingNotifierInterface', function()
{
return new SmsBillingNotifier;
});
Stand Alone Container 容器独立运行#
你的项目没有使用 Laravel?但你依然可以使用 Laravel 的 IoC 容器!只要用 Composer 安装了 illuminate/container 包就可以了。
容器的核心:通过 php 反射类实现(php 反射类,可以知道类的一切信息)
Reflect Resolution 反射解决方案#
//依靠这个强大的PHP特性, Laravel的IoC容器可以实现很有趣的功能!考虑接下来这个类
class UserController extends BaseController
{
public function __construct(StripBiller $biller)
{
$this->biller = $biller;
}
}
分析:
注意这个控制器的构造函数暗示着有一个 StripBiller 类型的参数。使用反射就可以检测到这种类型暗示。当 Laravel 的容器无法解决一个类型的明显绑定时,容器会试着使用反射来解决。程序流程类似于这样的:
- 已经有一个 StripBiller 的绑定了么?
- 没绑定?那用反射来探测一下 StripBiller 吧。看看他都需要什么依赖。
- 解决 StripBiller 需要的所有依赖(递归处理)
- 使用 ReflectionClass->newInstanceArgs () 来实例化 StripBiller
为何需要绑定接口实例#
class UserController extends BaseController
{
public function __construct(BillerInterface $biller)
{
$this->biller = $biller;
}
}
// 为何需要绑定接口实例
App::bind('BillerInterface','StripBiller');
分析:
假设我们没有为 BillerInterface 做任何绑定, 容器该怎么知道要注入什么类呢?
要知道,interface 不能被实例化,因为它只是个约定。如果我们不提供更多信息的话,容器是无法实例化这个依赖的。
所以,我们需要明确指出哪个类要实现这个接口 App::bind ('BillerInterface','StripBiller');
什么是反射?#
简易反射链接:博客:PHP 面向对象 (十一)反射类
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: