gandung / dependency-injection
依赖注入容器
v1.0.4
2017-06-25 12:43 UTC
Requires
- php: >=5.6.0 || >=7.1.0
- psr/container: ^1.0
Requires (Dev)
- phpunit/phpunit: ~4.0
- satooshi/php-coveralls: dev-master
- squizlabs/php_codesniffer: ^2.7.0
This package is auto-updated.
Last update: 2024-09-19 18:08:07 UTC
README
这是我的简单PHP依赖注入库
功能
- Can resolve class dependency that placed only on constructor (autowiring)
- Binding concrete dependency into unresolved abstract, either closure or class name.
- Can do shared binding concrete dependency into unresolved abstract, either closure or class name.
- Can resolve concrete implementation on typehinted interface on constructor method.
- Can resolve concrete implementation which bound on interface directly.
- Registering service under an alias.
尚未实现setter注入和方法注入。欢迎查看,或克隆以满足您的需求。
自动装配
假设您有一个类
<?php namespace Unused; class Foo { /** * @var \SplPriorityQueue */ private $heap; public function __construct(\SplPriorityQueue $heap) { $this->heap = $heap; } }
并且有一个依赖于 Unused\Foo 类的类,然而 Unused\Foo 类依赖于 \SplPriorityQueue 类
<?php namespace Unused; class Bar { /** * @var Foo */ private $foo; public function __construct(Foo $foo) { $this->foo = $foo; } }
您可以在不手动解决 Bar 和 \SplPriorityQueue 的情况下解决 Bar 类的实例
<?php use Unused\Bar; $container = new Container(); $bar = $container->make(Bar::class);
将具体依赖绑定到未解决的抽象(仅类名)
<?php use Unused\Bar; use Unused\Foo; $container = new Container(); $container->bind(Bar::class, Foo::class); $bar = $container->make(Bar::class);
现在,$bar 是 Bar::class 的实例。
将具体依赖绑定到未解决的抽象(使用闭包)
<?php use Unused\Bar; use Unused\Foo; $container = new Container(); $container->bind(Bar::class, function($container) { return $container->make(Foo::class); }); $bar = $container->make(Bar::class);
现在,$bar 也是 Bar::class 的实例。
共享绑定具体依赖到未解决的抽象(仅类名)
<?php use Unused\Base; use Unused\BaseInterface; $container = new Container(); $container->singleton(BaseInterface::class, Base::class); $base = $container->make(BaseInterface::class);
共享绑定具体依赖到未解决的抽象(使用闭包)
<?php use Unused\Base; use Unused\BaseInterface; $container = new Container(); $container->singleton(BaseInterface::class, function($container) { return $container->make(Base::class); }); $base = $container->make(BaseInterface::class);
将类型提示的接口绑定到未解决的抽象(基于类和闭包)
假设您有一个 BaseInterface 接口
<?php namespace Unused; interface BaseInterface { public function setFirstName($firstName); public function setMiddleName($middleName); public function setLastName($lastName); }
并且有一个在相同命名空间下实现 BaseInterface 接口的类
<?php namespace Unused; class Base implements BaseInterface { /** * @var string */ private $firstName; /** * @var string */ private $middleName; /** * @var string */ private $lastName; public function setFirstName($firstName) { $this->firstName = $firstName; } public function setMiddleName($middleName) { $this->middleName = $middleName; } public function setLastName($lastName) { $this->lastName = $lastName; } }
并且有一个在其构造函数中类型提示接口的类
<?php namespace Unused; class Foo { /** * @var BaseInterface */ private $base; public function __construct(BaseInterface $base) { $this->base = $base; } }
您可以通过首先绑定类 Base 到 BaseInterface 来解决类 Foo。
<?php use Unused\BaseInterface; use Unused\Base; use Unused\Foo; $container = new Container(); $container->bind(BaseInterface::class, Base::class); $foo = $container->make(Foo::class);
或者,您可以使用闭包绑定 BaseInterface 的具体实现
<?php use Unused\BaseInterface; use Unused\Base; use Unused\Foo; $container = new Container(); $container->bind(BaseInterface::class, function($container) { return $container->make(Base::class); }); $foo = $container->make(Foo::class);
直接解决绑定在接口上的具体实现
假设您有一个接口
<?php namespace Unused; interface BaseInterface { public function setFirstName($firstName); public function setMiddleName($middleName); public function setLastName($lastName); }
并且有一个实现 Unused\BaseInterface 的具体类
<?php namespace Unused; class Base implements BaseInterface { /** * @var string */ private $firstName; /** * @var string */ private $middleName; /** * @var string */ private $lastName; /** * @implements */ public function setFirstName($firstName) { $this->firstName = $firstName; } /** * @implements */ public function setMiddleName($middleName) { $this->middleName = $middleName; } /** * @implements */ public function setLastName($lastName) { $this->lastName = $lastName; } }
首先在该接口上绑定具体实现(可以使用直接类名或闭包)
<?php use Unused\Base; use Unused\BaseInterface; $container = new Container(); // with direct class name. $container->bind(BaseInterface::class, Base::class); // or, use a closure. $container->bind(BaseInterface::class, function($container) { return $container->make(Base::class); });
然后直接获取。
$base = $container->make(BaseInterface::class);
在别名下注册服务(PSR-11 兼容)
假设您有一个需要 BaseInterface 具体实现的服务
<?php namespace Unused; class FooService { /** * @var BaseInterface */ private $base; public function __construct(BaseInterface $base) { $this->base = $base; } }
只需绑定 BaseInterface 的具体实现,然后注册 FooService 到别名(例如:foo.service)
<?php $container = new Container(); $container->bind(BaseInterface::class, function($container) { return $container->make(Base::class); }); $container->register('foo.service', FooService::class); $service = $container->get('foo.service');
单元测试
如果您想运行单元测试
vendor/bin/phpunit
如果您需要更多详细信息
vendor/bin/phpunit --verbose