luna-fw / container
Requires (Dev)
- phpunit/phpunit: ^7
This package is auto-updated.
Last update: 2024-09-11 04:47:13 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);
上下文绑定(比如说,你想上传照片到谷歌照片,视频到油管)
<?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]联系我,我们可以讨论您如何帮忙。
目前,我们没有定义任何拉取请求流程,所以您可以帮我定义流程并成为其中的一员。