pmjones/caplet

一个符合PSR-11规范的极简自动装配依赖注入容器。

1.0.0 2023-04-19 22:32 UTC

This package is auto-updated.

Last update: 2024-08-29 18:27:11 UTC


README

Caplet是一个极简的自动装配依赖注入容器,用于处理基本的构造函数注入和对象工厂。

入门指南

如下实例化Caplet

use Caplet\Caplet;

$caplet = new Caplet();

然后您可以调用以下PSR-11方法之一

  • get(string $class) : object获取$class的共享对象实例。

  • has(string $class) : bool查看是否可获取实例。这意味着类定义存在;或者在接口的情况下,接口定义存在且包含一个factory()条目(请参阅下文的factory()方法)。

Caplet提供了一个非PSR-11方法

  • new(string $class) : object获取$class的新对象实例。(此方法不是PSR-11的一部分。)

配置

Caplet构建时,通过传递结构为$config['ClassName']['parameterName']的数组来配置非对象构造函数参数。例如,给定以下类...

namespace Foo;

class Bar
{
    public function __construct(
        protected string $bar,
        protected string $baz
    ) {
    }
}

...您将配置其参数的参数如下所示

use Caplet\Caplet;
use Foo\Bar;

$caplet = new Caplet([
    Bar::class => [
        'bar' => 'bar-value',
        'baz' => 'baz-value',
    ];
]);

$bar = $caplet->get(Bar::class);

或者,扩展Caplet并重写__construct()以接受您自己的环境或配置值,然后使用$config['ClassName']['parameterName']结构调用parent::__construct()

namespace Project;

use Caplet\Caplet;

class ProjectCaplet extends Caplet
{
    public function __construct(array $env)
    {
        parent::__construct([
            Foo::class => [
                'bar' => $env['BAR_VALUE'],
                'baz' => $env['BAZ_VALUE'],
            ],
        ]);
    }
}

工厂

扩展Caplet还允许您在构造函数中调用受保护的factory()方法来为给定类型定义对象创建逻辑。这允许您指定具体类以替代抽象或接口。例如

namespace Project;

use Caplet\Caplet;
use Project\Log\Logger;
use Psr\Log\LoggerInterface;

class ProjectCaplet extends Caplet
{
    public function __construct(
        string $bar,
        string $baz,
    ) {
        parent::__construct([
            Foo::class => [
                'bar' => 'bar-value',
                'baz' => 'baz-value',
            ],
        ]);

        $this->factory(
            LoggerInterface::class,
            fn (Caplet $caplet) => $caplet->get(Logger::class)
        );
    }
}

如上所示,可调用的工厂逻辑必须具有function (Caplet $caplet)的签名,并可以指定返回类型。

构造函数参数解析

Caplet将按以下顺序尝试解析构造函数参数

  • 首先,使用从$config中提供的参数,如果有的话。
  • 其次,尝试获取参数类型的对象。
  • 最后,使用默认参数值,如果已定义的话。

如果以上所有方法都不起作用,Caplet将抛出Exception\NotInstantiated,之前是Exception\NotResolved异常。