ronanchilvers/container

一个非常简单、PSR-11 兼容的容器

2.0 2022-11-25 18:43 UTC

This package is auto-updated.

Last update: 2024-09-25 22:42:19 UTC


README

Build Status codecov Software License

这是一个简单、小巧的符合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许可协议许可。请参阅许可文件以获取更多信息。