此外/无障碍/容器和服务/集装箱使用不规范

容器的非标准使用


#初始化服務中的服務

尽管通过new和空构造函数在容器中创建对象是一个良好的实践,最终,您可以将所有必要依赖项的创建委托给一个特殊类中的单独方法,并在容器中注册其执行。不过,也有方法可以在不创建单独包装类的情况下解决依赖关系。

如果需要重用容器中的服务来初始化容器中的另一个服务,我们可以借助依赖注入提供的功能。在类App\Bootstrap\ContainerFactory中,这些方法是可用的,就像在用于创建容器的特殊类中一样。

例如,必须初始化容器中的服务构造函数。为此,在App\Bootstrap\ContainerFactory类的match运算符体内,您需要添加以下匹配项:

// File /app/Bootstrap/ContainerFactory.php
use Hleb\Static\DI;
// ... //

ExampleService::class => new ExampleService(),

// variant 1
DemoService::class => new DemoService(DI::object(ExampleService::class)),

// variant 2
DemoService::class => DI::object(DemoService::class),

// ... //

现在,在DemoService类的构造函数中,当前的ExampleService将按照容器中的定义注入。使用的示例中未明确指定的所有依赖项将自动解决(变体2)。

重要的是确保依赖关系不会形成循环依赖,这种情况可能发生在容器中的对象再次请求容器以初始化其自身时。

更复杂的示例:

// File /app/Bootstrap/ContainerFactory.php
use Hleb\Static\DI;

// ... //

SenderServiceInterface::class => new MailTransportService(),

SiestaService::class => DI::method(DI::object(
    
SiestaService::class,
    [
        
'start' => (new DateTimeImmutable())->setTime(140),
        
'end' => (new DateTimeImmutable())->setTime(160),
    ]
), 
'setSender', ['transport' => DI::object(SenderServiceInterface::class)]),

// ... //

通过这种方式,尽管框架容器看似简单,您可以添加各种相互依赖的服务。


#在用户代码中添加服务

默认情况下,框架不允许在容器初始化后添加服务。然而,通过在 ContainerFactory 类中将 getSingleton() 方法重写为公共的,你可以通过这个静态方法在用户代码中将对象添加到容器中。以下是修改类的示例:

// File /app/Bootstrap/ContainerFactory.php

use Hleb\Constructor\Containers\BaseContainerFactory;

final class 
ContainerFactory extends BaseContainerFactory
{
    public static function 
getSingleton(string $id): mixed
    
{
        
// ... //

        
if (is_callable(self::$singletons[$id])) {
            
self::$singletons[$id] = self::$singletons[$id]();
        }
        return 
self::$singletons[$id];
    }

    #[\Override]
    public static function 
setSingleton(string $idobject|callable|null $value): void
    
{
        
parent::setSingleton($id$value);
    }
}

从示例可以看出,还增加了通过 callable 类型及其处理程序的延迟初始化支持。

页面翻译:chatgpt 4-o
返回顶部