scruwi / container
PSR-11 容器实现
v0.1.1
2021-09-27 18:49 UTC
README
这是我自己的PSR-11容器接口实现。
安装
composer require scruwi/container
初始化
$container = new Container([ new ClassResolver(['App\\Namespace1', 'App\\Namespace2']), new ParameterResolver(['param1' => true, 'param2' => 'string']), new DefinitionResolver([Definition1:class, Definition2:class]), ]);
解析器
ClassResolver
- 定义允许自动注入的命名空间ParameterResolver
- 定义可以设置到构造函数中的标量参数DefinitionResolver
- 定义到定义的路径
如果需要,你可以在项目中实现自己的解析器。查看 Interfaces
命名空间。
ClassResolver
只有定义的命名空间中的类可以进行自动注入。
ParameterResolver
典型用法
$rootParameters = ['param1' => true, 'param2' => 'string']; $classSpecificParameters = [SpecificClass::class => ['param1' => false]]; $resolver = ParameterResolver($rootParameters, $classSpecificParameters);
预期行为
class SomeClass { public function __construct(bool $param1) { /* $param1 === true */ } }
class SpecificClass { public function __construct(bool $param1) { /* $param1 === false */ } }
具有默认值的参数不必由配置解析
class SpecificClass { public function __construct(bool $param0 = 'default') { /* $param0 === 'default' */ } }
你可以创建一个特定的解析器并按自己的方式使用它。只需实现 ParameterResolverInterface
并在容器构造时指定它。
DefinitionResolver
将定义附加到容器。
定义,它不过是一个以特定方式创建对象的工厂。有一个特定的 ReflectionClassDefinition
通过反射构造类。所有自动注入的类都使用这个工厂来创建它们的对象。
你应该在你的项目中创建尽可能多的定义,并在容器构造时指定它们,或者稍后通过 $container->addDefinition()
方法附加它们。任何定义都必须实现 DefinitionInterface
。
典型的定义类如下所示
class ExampleDefinition implements DefinitionInterface { public static function getId(): string { return ExampleClass::class; } public function __invoke(Container $container, ParameterResolver $resolver, BuildContext $context): object { return new ExampleClass(); } }
你可以从 ParameterResolver 获取一些默认参数
public function __invoke(Container $container, ParameterResolver $resolver, BuildContext $context): object { $param1 = $resolver->resolve('param1', ExampleClass::class); return new ExampleClass($param1); }
你还可以找出它是从哪个上下文调用的。这可能在自动注入接口时很有用
class InterfaceDefinition implements DefinitionInterface { public function getId(): string { return SomeInterface::class; } public function __invoke(Container $container, ParameterResolver $resolver, BuildContext $context): object { if ($context->getTargetClass() === ClassWithInterfaceDependency::class) { return new SomeClassImplementsInterface2(); } return new SomeClassImplementsInterface1(); } }
异常
NotFoundExceptionInterface
- 对于未知条目ContainerExceptionInterface
- 对于容器中的所有通用异常CircularReferencesException
- 容器中存在循环引用时有一个特殊的异常