此外/无障碍/容器和服务/集装箱使用不规范
容器的非标准使用
#初始化服務中的服務
尽管通过new和空构造函数在容器中创建对象是一个良好的实践,最终,您可以将所有必要依赖项的创建委托给一个特殊类中的单独方法,并在容器中注册其执行。不过,也有方法可以在不创建单独包装类的情况下解决依赖关系。
如果需要重用容器中的服务来初始化容器中的另一个服务,我们可以借助依赖注入提供的功能。在类App\Bootstrap\ContainerFactory中,这些方法是可用的,就像在用于创建容器的特殊类中一样。
例如,必须初始化容器中的服务构造函数。为此,在App\Bootstrap\ContainerFactory类的match运算符体内,您需要添加以下匹配项:
use Hleb\Static\DI;
ExampleService::class => new ExampleService(),
DemoService::class => new DemoService(DI::object(ExampleService::class)),
DemoService::class => DI::object(DemoService::class),
现在,在DemoService类的构造函数中,当前的ExampleService将按照容器中的定义注入。使用的示例中未明确指定的所有依赖项将自动解决(变体2)。
重要的是确保依赖关系不会形成循环依赖,这种情况可能发生在容器中的对象再次请求容器以初始化其自身时。
更复杂的示例:
use Hleb\Static\DI;
SenderServiceInterface::class => new MailTransportService(),
SiestaService::class => DI::method(DI::object(
SiestaService::class,
[
'start' => (new DateTimeImmutable())->setTime(14, 0),
'end' => (new DateTimeImmutable())->setTime(16, 0),
]
), 'setSender', ['transport' => DI::object(SenderServiceInterface::class)]),
通过这种方式,尽管框架容器看似简单,您可以添加各种相互依赖的服务。
#在用户代码中添加服务
默认情况下,框架不允许在容器初始化后添加服务。然而,通过在 ContainerFactory 类中将 getSingleton() 方法重写为公共的,你可以通过这个静态方法在用户代码中将对象添加到容器中。以下是修改类的示例:
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 $id, object|callable|null $value): void
{
parent::setSingleton($id, $value);
}
}
从示例可以看出,还增加了通过 callable 类型及其处理程序的延迟初始化支持。
页面翻译:chatgpt 4-o