IOC 容器
目前系统所有的关键服务都接入了 IOC 容器,包括控制器、Console 命令行。
引入相关类
- use Leevel\Di\Container;
- use Leevel\Di\ICoroutine;
- use stdClass;
闭包属于惰性,真正使用的时候才会执行。
通常来说,系统大部分服务都是单例来提升性能和共享。
闭包绑定单例
public function testSingletonClosure()
{
$container = new Container();
$singleton = new stdClass();
$container->singleton('singleton', function () use ($singleton) {
return $singleton;
});
$this->assertSame($singleton, $container->make('singleton'));
}
一个独立的类可以直接生成,而不需要提前注册到容器中。
public function testClass()
{
$container = new Container();
}
类单例
类也可以注册为单例。
public function testInterface()
{
$container = new Container();
$container->bind(ITest2::class, Test2::class);
$this->assertInstanceOf(ITest2::class, $container->make(ITest2::class));
$this->assertInstanceOf(ITest2::class, $container->make(Test2::class));
}
接口绑定接口作为构造器参数
接口可以作为控制器参数来做依赖注入。
ITest2 定义
namespace Tests\Di\Fixtures;
interface ITest2
{
Test2 定义
namespace Tests\Di\Fixtures;
class Test3 implements ITest3
public $arg1;
public function __construct(ITest2 $arg1)
{
$this->arg1 = $arg1;
}
}
通过 Test3
的构造函数注入 ITest2
的实现 Test2
,通过 IOC 容器可以实现代码解耦。
public function testInterface2()
{
$container = new Container();
$container->bind(ITest2::class, Test2::class);
$this->assertInstanceOf(ITest2::class, $test2 = $container->make(Test3::class)->arg1);
$this->assertInstanceOf(Test2::class, $test2);