kbondurant / self-provider-container

从您的服务内部声明定义

1.0.1 2022-02-28 18:59 UTC

This package is auto-updated.

Last update: 2024-09-03 21:31:30 UTC


README

league/container 提供一个代理容器。

直接从您的服务中声明定义,在您第一次检索它之前

安装

通过 Composer

composer require kbondurant/self-provider-container

要求

此版本支持的 PHP 版本如下。

  • PHP 8.0
  • PHP 8.1

用法

如果您也使用 ReflectionContainer,应先添加 SelfProviderContainer。

use Kbondurant\SelfProviderContainer\SelfProviderContainer;
use League\Container\Container;
use League\Container\ReflectionContainer;

$container = new Container();

$container->delegate(new SelfProviderContainer());
$container->delegate(new ReflectionContainer());

现在您可以实现 ServiceProvider 接口(或任何扩展它的接口),并在 register 方法中添加您的定义。当您第一次尝试从容器中检索 LeagueRouter 时,它将首先调用 register 方法,然后再尝试实例化。

class LeagueRouter implements ServiceProvider
{
    public function __construct(
        private Router $router,
    ) {
    }

    /**
     * @param \League\Container\DefinitionContainerInterface $container
     * @return void
     */
    public static function register(mixed $container): void
    {
        $container->add(Router::class, fn () => new Router())
            ->setShared(true);
    }
}

默认情况下,register::method 将传递 League\Container\DefinitionContainerInterface 的一个实例,但您可以通过将您自己的容器实例传递给 SelfProviderContainer 来改变这一点

use Acme\Container\MyOwnContainer;
use Kbondurant\SelfProviderContainer\SelfProviderContainer;
use League\Container\Container;
use League\Container\ReflectionContainer;

$container = new Container();

$container->delegate(new SelfProviderContainer(new MyOwnContainer()));
$container->delegate(new ReflectionContainer());

现在 register 方法将传递 Acme\Container\MyOwnContainer 的一个实例

class LeagueRouter implements ServiceProvider
{
    public function __construct(
        private Router $router,
    ) {
    }

    /**
     * @param \Acme\Container\MyOwnContainer $container
     * @return void
     */
    public static function register(mixed $container): void
    {
        $container->singleton(Router::class, fn () => new Router());
    }
}

限制

仅在即将注册的服务(适配器等)只在一个类中注入时使用此模式,否则您可能会多次重新声明相同的服务,这可能会导致性能缓慢或出现共享定义的漏洞