wlib / dibox
DiBox 是一个依赖注入容器。
v1.2.0
2023-12-17 23:12 UTC
Requires
- php: >=7.4.0
- psr/container: ^2.0
Requires (Dev)
- pestphp/pest: ^2.8
This package is auto-updated.
Last update: 2024-09-18 00:46:06 UTC
README
DiBox 是一个依赖注入容器。它遵循 PSR-11 指令。
安装
composer require wlib/dibox
使用
use wlib\Di\DiBox; $box = new DiBox();
实例化对象
容器可以用于简单地实例化对象
// Créer une instance de Foo\Bar $bar = $box->make(Foo\Bar::class); // Passer des arguments au constructeur $bar = $box->make(Foo\Bar::class, ['a', 'b']); // indexés $bar = $box->make(Foo\Bar::class, ['sGreetings' => 'Hello']); // nommés, ici, le constructeur attend l'entrée `$sGreetings`
通过容器的好处是能够自动解析构造函数所需的类
class Bar { public function __construct(public Baz $baz); } class Baz {} $bar = $box->make(Bar::class); // $bar->baz sera une instance de Baz
声明依赖
实例化已经不错,但定义依赖更好,特别是为了构建应用程序
直接依赖
不一定最有用,但它是有效的
$box->bind(Foo\Bar::class); $bar = $box->get(Foo\Bar::class); // instance de Foo\Bar
创建别名
为所有人取别名(或者整理容器,看你的需要)
$box->bind('MyBar', Foo\Bar::class); $bar = $box->get('MyBar'); // toujours une instance de Foo\Bar mais depuis son p'tit nom
现有实例
如果需要
$bar = new Foo\Bar(); $box->bind('MyBar', $bar); $samebar = $box->get('MyBar'); // toujours pareil !
创建关闭
或者 Closure
对专业人士来说。从这里开始,事情变得有趣,变得有意义。
$box->bind('MyBaz', function($box, $args) { return new Foo\Baz($box->get('MyBar')); }); $baz = $box->get('MyBaz'); // instance de Foo\Baz prête à bosser, classe non ?
所以,你面前展现出了无限的可能性!
标量值
你可以最多,也可以最少,你还可以在容器中存储简单的值
$box->bind('one.string', 'DiBox has all of a great one !'); $box->bind('one.integer', 2023); $box->bind('one.array', [1, 2, 3]); echo $box->get('one.string')); // Affiche "DiBox has ...') echo $box->get('one.integer')); // Affiche "2023" echo $box->get('one.array')); // Attention piège, ça affiche quoi ?
“ArrayAccess” 模式
容器实现了 ArrayAccess
接口
$box['make.b'] = function ($box, $args) { return new B(new A()); }; $box['integer'] = 4046; $box['list'] = ['a', 'b', 'c']; $box['class.a'] = A::class; $b = $box['make.b']; // instance de B $iInteger = $box['integer']; // 4096 $aList = $box['list']; // cf. 5 lignes au dessus $a = $box['class.a']; // bon, vous maîtrisez normalement
因此,你可以使用 isset()
和 unset()
unset($box['class.a']); isset($box['class.a']); // >> false
共享依赖(单例)
你可以根据需要共享依赖:单例模式(但比单例模式更好,因为你知道即使它很有用,创建真正的单例也不总是最佳实践)
class Counter { protected $count = 0; public function increment(): int { return $this->count++; } } $box->singleton(Counter::class); echo $box->get(Counter::class)->increment(); // 0 echo $box->get(Counter::class)->increment(); // 1 echo $box->get(Counter::class)->increment(); // 2
其他方法
以下是一些需要了解的方法
$box->has('MyBar'); // pour vérifier la présense d'une dépendance $box->remove('MyBar'); // pour retirer cette dépendance que vous ne voulez plus voir $box->empty(); // pour vider le conteneur
依赖提供者
你还在这里?声明许多依赖并填充容器是很好,但你可能正在开发一个可能不知道将如何处理所有依赖的应用程序,或者你只是想在你不同的命名空间/包中组织这一切。
因此,你需要创建提供者,它们将负责在容器中注入它们的依赖。
因此,现在是时候实现 wlib\Di\DiBoxProvider
合约了。
// Exemple (classique ?) d'un fournisseur des services HTTP d'une application class HttpProvider implements DiBoxProvider { public function provide(DiBox $box) { $box->bind('http.request', function($box, $args) { return MyApp\Http\Request(); }); $box->bind('http.response', function($box, $args) { return MyApp\Http\Response($box['http.request']); }); } } // Et pour le fournir au conteneur, rien de plus simple : $box->register(HttpProvider::class); $response = $box->get('http.response'); // Et vous avez une réponse HTTP prête à servir vos applications / API
好了,你已经掌握了!现在轮到你发挥作用了。
异常
如果出现故障,无论是故意的还是意外的,DiBox
可能会引发以下异常
wlib\Di\DiException
:在容器不高兴的时候抛出wlib\Di\DiNotFoundException
:符合 PSR-11,如果你尝试访问不存在的依赖,则会抛出
单元测试
不要犹豫,查看 /tests/Unit/DiBoxTest.php
文件,它将为您提供有关如何使用 DiBox
的额外技术细节。
单元测试使用了 Pest 库。