ronanchilvers / container
一个非常简单、PSR-11 兼容的容器
2.0
2022-11-25 18:43 UTC
Requires
- php: ^8.0
- psr/container: ^1.0
Requires (Dev)
README
这是一个简单、小巧的符合PSR-11规范的容器,适用于PHP 7+。它具有以下功能
- 工厂和共享定义
- 支持非对象服务(例如:存储键值对)
- 别名
- 自动装配
安装
最简单的方法是通过composer安装
composer install ronanchilvers/container
使用方法
基本使用很简单
$container = new Container; $container->set('my_service', function () { return new \My\Service(); }); $myService = $container->get('my_service');
默认情况下,添加到容器的服务是工厂服务 - 每次都会得到一个新的实例。如果您想定义一个共享服务,可以这样做
$container = new Container; $container->share('my_shared_service', function () { return new \My\Service(); }); $sharedService = $container->get('my_shared_service');
您还可以在容器中注册原始数据
$container = new Container; $container->set('settings', [ 'db' => [ 'adaptor' => 'mysql', 'username' => 'foobar', 'password' => 'supersecret', 'hostname' => '127.0.0.1' ] ]); $container->set('my_string', 'foobar'); $settings = $container->get('settings'); $settings = $container->get('my_string');
别名
有时能够为服务创建别名很有用。例如,如果您想使用简单的字符串名称注册一个服务,但也要通过接口名称引用它。为此,您可以在定义中使用Symfony风格的指定前缀来指示这是一个对另一个服务的引用。
以下是一个示例
$container = new Container; $container->share('logger', function (){ return new PSR11Logger(); }); $container->set('Psr\Log\LoggerInterface', '@logger'); // This: $logger = $container->get('logger'); // returns the same instance as this: $logger = $container->get('Psr\Log\LoggerInterface');
扩展服务
容器允许使用extend()
方法扩展服务(就像Pimple一样)。您可以扩展工厂和共享服务。通过服务ID和可调用对象调用extend()
。可调用对象将接收服务实例作为第一个参数,容器作为第二个参数。您可以多次扩展服务。
$container = new Container; $container->share('my_service', function () { return new \My\Service; }); $container->extend('my_service', function ($s, $c) { $s->registerWidget(new Widget); return $s; }); $service = $container->get('my_service');
自动装配
容器支持基本的自动装配。这意味着您可以将完全限定的类名作为服务定义提供,容器将尝试为您实例化它。
$container = new Container; $container->set('logger', '\App\MyLogger'); $logger = $container->get('logger');
还支持类型提示参数的构造函数注入。
use Psr\Log\LoggerInterface; class MyLogger implements LoggerInterface { ... } class MyService { public function __construct(LoggerInterface $logger) { ... } } $container = new Container; $container->share(LoggerInterface::class, 'MyLogger'); $container->share(MyService::class, 'MyService'); // This will return an instantiated service with the logger injected $service = $container->get(MyService::class);
注入的对象无需在容器中注册即可注入。如果容器遇到未定义为服务的依赖项,它将尝试创建一个不带构造函数参数的新实例。
服务提供者
容器支持Pimple风格的提供者。您的提供者必须实现Ronanchilvers\Container\ServiceProviderInterface
。
class ServiceProvider implements ServiceProviderInterface { /** * @author Ronan Chilvers <ronan@d3r.com> */ public function register(Container $container) { $container->set('my_service', function () { return new StdClass; }); } } $container = new Container; $container->register(new ServiceProvider); $myService = $container->get('my_service');
测试
容器非常简单,并且有100%的测试覆盖率。您可以通过这样做来运行测试
./vendor/bin/phpunit
默认的phpunit.xml.dist文件在build/coverage子目录中创建覆盖率信息。
贡献
如果有人有任何要贡献的补丁,我将非常乐意审查它们。请提出一个PR。你应该
- 遵循PSR2
- 保持100%的测试覆盖率,或者给出您不这样做的原因
- 遵循每个pull请求一个功能的规则
许可
本软件受MIT许可协议许可。请参阅许可文件以获取更多信息。