luna-fw /djinn
Requires (Dev)
- phpunit/phpunit: ^7
This package is not auto-updated.
Last update: 2024-09-18 15:18:29 UTC
README
Djinn 是一个功能齐全的 PHP 依赖注入容器。我们称之为 Djinn,因为依赖注入容器就像一个精灵:它给予主人(调用者)愿望(依赖项)。
安装
必须使用 composer 安装此包
composer require luna-fw/djinn
或者在您的 composer.json
依赖中包含 luna-fw/djinn
。
用法
此包实现了 PSR-11 接口和异常
Psr\Container\ContainerInterface
has(key)
- 根据字符串键返回实例get(key)
- 如果给定实例存在,则返回 true
Psr\Container\ContainerExceptionInterface
Psr\Container\NotFoundExceptionInterface
有关详细信息,请参阅:https://www.php-fig.org/psr/psr-11/
我们认为 PSR-11 规范过于简单,因此我们在实现中添加了一些额外的接口(这些扩展实现不会阻止某人将其用作 PSR-11 兼容容器)。
以下是扩展接口
ContainerConfigContract
- 包含与容器配置相关的函数。bind
- 配置给定键的解析singleton
- 配置给定键的解析,始终返回不可变实例(单例)。contextual
- 与 bind 相同,但解析取决于“谁”请求实例。contextualSingleton
- 与 contextual 相同,但始终返回不可变实例(单例)。
ExtendedContainerContract
- 包含与 DI 注入/解析相关的函数。getFor
- 根据定义的配置返回所需的类或接口的实例,解析所有依赖项。允许上下文绑定。run
- 执行方法,解析其所有依赖项,根据定义的配置。
要使用它,您需要包含 vendor/autoload.php
文件。然后,您只需实例化 Luna\Djinn
类并开始使用它。
<?php require 'vendor/autoload.php'; // keep the container instance available globally $djinn = new \Luna\Djinn(); // configure the bindings $djinn->bind(FooContract::class, function() { return new FooClass('paramether'); }); // every time you need an instance that implements FooContract, you call the get method $foo = $djinn->get(FooContract::class); echo get_class($foo); // prints FooClass
这是 DI 容器的最简单用法。在实际环境中,您可能希望将容器的所有配置分散在特定的文件中(例如 dependencies.php 或类似文件),并将所有对容器方法的调用推送到系统的“边缘”(可能是路由器),因为 PSR-11 建议不要将容器对象传递给其他对象。
请注意,我们在解析时始终有两个步骤
- 配置容器,让它知道如何解析您的依赖项。
- 使用容器
一些重要注意事项
- 如果您的愿望是一个有效的类,并且在它的构造函数中不接受任何参数,它将自动实例化。
- 如果您的愿望是一个有效的类,并且它的构造函数参数可以通过容器解析,它们将被递归解析。
- 一个常见用法是使用接口作为愿望,并使用类名作为授权,在这种情况下,授权的类将被解析并授权。
- 可以对同一愿望有多个绑定(即对同一接口有多个实现),根据愿望者的不同进行授权。例如,如果从不同位置调用相同的接口,您可以根据上下文得到不同的结果。
- 在自动解析构造函数或方法的参数时,我们始终首先尝试使用变量名称解析,然后使用类型提示。
- 我们还可以通过Djinn运行一个函数/方法,它会尝试解决所有依赖。这在构建路由器时特别有用,因为您不需要手动通过构造函数注入所有内容。
- 我们还提供了单例绑定选项,它总是为相同的愿望返回相同的实例。
配置/绑定示例
简单绑定
<?php $djinn->bind(FooClass::class, function() { return new FooClass('paramether'); }); $djinn->bind('barservice', function() { return new BarClass($djinn->get(FooClass::class)); });
绑定单例(相同的内容,但Djinn总是返回相同的对象)
<?php $djinn->singleton(FooClass::class, function() { return new FooClass('paramether'); });
将接口绑定到实现
<?php $djinn->bind(FileUploaderInterface::class, YoutubeUploader::class);
上下文绑定(比如说,您想要上传照片到谷歌照片,视频到YouTube)
<?php $djinn->contextual(PhotoContoller::class, FileUploaderInterface::class, GooglePhotosUploader::class); $djinn->contextual(VideoController::class, FileUploaderInterface::class, YoutubeUploader::class);
绑定原始数据类型(并运行一个方法)
<?php $djinn->contextual(FooClass::class.':sum', '$value1', 3); $djinn->contextual(FooClass::class.':sum', '$value2', 7); $djinn->run('sum', $djinn->get(FooClass::class)); // returns 10
要了解更多关于此容器使用的示例,请参阅tests
文件夹下的测试。
测试
要在包上运行测试,首先运行composer install
,然后转到根目录,并运行以下命令之一
在Linux/Unix上
./vendor/bin/phpunit
在Windows上
.\vendor\bin\phpunit.bat
或者在任何平台上
php ./vendor/phpunit/phpunit/phpunit
您可以使用所有phpunit选项。
贡献
Luna框架仍然是一个非常初期的项目。我刚刚开始,到目前为止我一个人在做。
如果您想贡献,请通过[email protected]联系我,我们可以讨论您如何提供帮助。
目前,我们还没有定义任何关于拉取请求的过程,所以您可以帮助我定义这个过程,并成为其中的一员。