bigbit / oddin
按需依赖注入
Requires
- php: ~7.4.0
- psr/simple-cache: ^1.0
Requires (Dev)
- bigbit/di-bootstrap: ~2.0.0
- bigbit/smart-di: ~2.0.0
- phpstan/phpstan: ^0.11.15
- phpunit/phpunit: ^8.2
- symfony/cache: ^4.3.8
- symfony/console: ^4.3
- tracy/tracy: ^2.6
Suggests
- bigbit/smart-di: ~2.0.0
- symfony/cache: ^4.3
This package is auto-updated.
Last update: 2024-09-20 23:58:13 UTC
README
关于
有时候编程很痛苦。你的老板需要它现在,或者你只是无聊地一遍又一遍地写甜话...
如果你在项目中使用依赖注入,你必须在构造函数中编写属性声明并初始化它们。你可以使用依赖容器或定义可注入的构造函数参数。这取决于使用的框架。仅限PHP7.4.0,7.4.1破坏了功能,php bug #78904。
class Foo { private Dependency1 $dep1; private Dependency2 $dep2; private Depencency3 $dep3; function __construct(Dependency1 $dep1, Dependency2 $dep2, Container $container) { $this->dep1 = $dep1; $this->dep2 = $dep2; $this->dep3 = $container->get(Dependency3::class); } public function bar() { $this->dep1->doSomething(); } protected function baz() { $this->dep2->doSomethind(); } private function bye() { $this->dep3->doSomething(); } }
使用ODDIN,你可以跳过构造函数部分。只需声明属性,并在需要时访问它们。请注意,这些属性可以通过魔法 __get 方法在任何地方访问。你的首选IDE将帮助你处理这个问题。
class Foo { use InjectsOnDemand; private Dependency1 $dep1; private Dependency2 $dep2; private Depencency3 $dep3; /** * Foo constructor. * as of php7.4.1, we have to unset properties in constructor * https://bugs.php.net/bug.php?id=78904 */ public function __construct() { unset($this->dep1, $this->dep2, $this->dep3); } public function bar() { $this->dep1->doSomething(); } private function baz() { $this->dep2->doSomething(); } private function bye() { $this->dep3->doSomethind(); } }
它的工作原理
PHP类可以有魔法方法。每当你要使用未设置属性时,都会调用__get魔法方法。DIResolver使用解析器从类或过时的属性注释中获取依赖元数据。InjectOnDemand trait定义了一个魔法__get方法,用于处理所有的属性请求。一旦属性通过特质初始化,魔法方法就不再调用。
优点
- 更少的代码
- 按需实例化依赖(懒加载 - 不在构造函数之前,如果正确定义在DI容器中)
缺点
- 所有属性都变成公开的吗?所有可注入的都是“公开”的
- 反模式?仅用于原型设计,稍后清理代码。
目的
更干净的控制器类,更少的资源需求。但这是你自己的选择,在哪里使用ODDIN。
已知问题
- 尚未提供代码修复器
快速入门
你可以使用任何实现了Psr\Container\ContainerInterface的DI容器。为了快速入门,你可以使用Bootstrap类,它使用SmartContainer。
use BigBIT\DIBootstrap\Bootstrap; use Psr\Container\ContainerInterface; // custom bindings $bindings = [ FooInterface::class => function(ContainerInterface $container) { return new BarImplementation( $container->get(BazDependency::class) ); } ]; $container = Bootstrap::getContainer($bindings); $app = new SomeApp($container); $app->run();
其他框架
你可以请求其他框架支持或基于Bootstrap类编写你自己的引导。
PHP-DI比较
@todo
缓存生成器
已添加了缓存生成器的实验性实现。如果你的项目安装了phpstan,建议也安装tracy/tracy。Oddin使用Psr\SimpleCache\CacheInterface实现和Symfony作为默认。
创建缓存不是必需的,但建议在生产环境中创建。
vendor/bin/oddin cache:injectables:create php-files -a oddin -a 0 -a cache
cli命令的参数是从适配器构造函数中推导出来的。
实例化缓存
$bindings[CacheInterface::class] = function(ContainerInterface $container) { return new Psr16Cache(new PhpFilesAdapter('oddin', 0, dirname(__DIR__) . '/cache')); };
@TODO - 代码修复器
cli命令用于修复代码。它将删除类属性注释,声明属性,并在构造函数中添加或获取器和容器。