tobento/service-container

一个具有自动注入功能的PSR-11容器。

1.0.7 2023-11-29 17:14 UTC

This package is auto-updated.

Last update: 2024-09-29 19:06:36 UTC


README

容器服务提供具有自动注入功能的PSR-11容器。

目录

入门指南

使用以下命令添加运行容器服务的最新版本。

composer require tobento/service-container

要求

  • PHP 8.0或更高版本

亮点

  • 框架无关,适用于任何项目
  • 解耦设计
  • 自动注入

文档

PSR-11

use Tobento\Service\Container\Container;

$container = new Container();

$has = $container->has(Foo::class);

$foo = $container->get(Foo::class);

自动注入

容器通过自动注入解决任何依赖关系,除了需要定义才能解决的内置参数。

对于联合类型参数,如果没有通过定义设置,则使用第一个可解析的参数。

定义

通过提供解析后的对象

use Tobento\Service\Container\Container;

class Foo
{
    public function __construct(
        private string $name
    ) {} 
}

$container = new Container();

$container->set(Foo::class, new Foo('value'));

$foo = $container->get(Foo::class);

通过定义缺失的参数

use Tobento\Service\Container\Container;

class Foo
{
    public function __construct(
        private string $name
    ) {} 
}

$container = new Container();

// By the construct method:
$container->set(Foo::class)->construct('value');

// By the with method using parameter name:
$container->set(Foo::class)->with(['name' => 'value']);

// By the with method using parameter position:
$container->set(Foo::class)->with([0 => 'value']);

$foo = $container->get(Foo::class);

通过使用闭包

容器将自动解析任何闭包参数。

use Tobento\Service\Container\Container;

class Foo
{
    public function __construct(
        private string $name
    ) {} 
}

class Bar
{
    public function value(): string
    {
        return 'value';
    } 
}

$container = new Container();

$container->set(Foo::class, static function(Bar $bar) {
    return new Foo($bar->value());
});

$foo = $container->get(Foo::class);

您可以配置要使用哪种实现

$container->set(BarInterface::class, Bar::class);

定义方法调用:如果您想进行自动注入,则只需定义内置参数即可,其他参数将被自动注入。

use Tobento\Service\Container\Container;

class Foo
{
    public function index(Bar $bar, string $name) {} 
}

class Bar {}

$container = new Container();

$container->set(Foo::class)->callMethod('index', ['name' => 'value']);

$container->set(Foo::class)->callMethod('index', [1 => 'value']);

$foo = $container->get(Foo::class);

原型定义

您可以声明定义为原型,意味着总是返回一个新实例。

use Tobento\Service\Container\Container;

class Foo {}
class Bar {}

$container = new Container();

$container->set(Foo::class)->prototype();

$container->set(Bar::class, function() {
    return new Bar();
})->prototype();

var_dump($container->get(Foo::class) === $container->get(Foo::class));
// bool(false)

var_dump($container->get(Bar::class) === $container->get(Bar::class));
// bool(false)

Make

make()方法类似于get(),但它会在每次调用时解析条目。

use Tobento\Service\Container\Container;

class Foo
{
    public function __construct(
        private Bar $bar,
        private string $name
    ) {} 
}

class Bar {}

$container = new Container();

$foo = $container->make(Foo::class, ['name' => 'value']);

Call

更多详细信息,请访问:service-autowire#call

class Foo
{
    public function index(Bar $bar, string $name): string
    {
        return $name;
    } 
}

class Bar {}

$container = new Container();

$name = $container->call([Foo::class, 'index'], ['name' => 'value']);

解析器

您可以通过添加实现以下接口的自定义解析器来调整您的需求

use Tobento\Service\Container\Container;
use Tobento\Service\Container\ResolverInterface;

$container = new Container(new CustomResolver());
/**
 * ResolverInterface
 */
interface ResolverInterface
{    
    /**
     * Resolve the given identifier to a value.
     *
     * @param string $id Identifier of the entry.
     * @param array<int|string, mixed> $parameters
     *
     * @return mixed
     */
    public function resolve(string $id, array $parameters = []): mixed;

    /**
     * Resolve the given definition.
     *
     * @param DefinitionInterface $definition
     *
     * @return mixed The value of the resolved definition.
     */
    public function resolveDefinition(DefinitionInterface $definition): mixed;
    
    /**
     * If the given identifier is resolvable.
     *
     * @param mixed $id Identifier of the entry.
     * @return bool True if resolvable, otherwise false.
     */
    public function isResolvable(mixed $id): bool;
}

致谢