moro /
PHP-7 的依赖注入容器
Requires
- psr/container: 1.0.0
Requires (Dev)
- codeception/assert-throws: ~1.0
- codeception/codeception: ~2.3
- codeception/specify: ~1.0
- codeception/verify: ~1.0
- infection/infection: ~0.5
Provides
- psr/container-implementation: 1.0.0
This package is auto-updated.
Last update: 2024-09-17 10:17:02 UTC
README
Container7 是一个中等大小的 PHP-7 依赖注入容器。
本包符合 PSR-1、PSR-2、PSR-4 和 PSR-11。如果发现合规性问题,请通过 pull request 提交补丁。
特性:提供者、单例、工厂、参数、别名、标签、配置、序列化。
安装
通过 composer
$ composer require moro/container7
要求
- PHP 7.1
使用
创建容器是创建 Container 实例的问题。
<?php use Moro\Container7\Container; $container = new Container();
与其他依赖注入容器类似,Container7 管理两种不同类型的数据:服务和参数。服务通过它们的类或别名从容器中接收。参数存储在它们的服务的 "参数" 中。
<?php if ($container->has(Service::class)) { $service = $container->get(Service::class); } $value = $container->get('parameters')->get('key');
用于服务定义的 Service Providers。
<?php $container->addProvider(SomeProvider::class);
Service Providers 允许您将代码或配置打包到您经常重用的包中。
Service provider
任何 Service Provider 都是一个简单的 PHP 类。服务通过返回对象实例的方法来定义。您必须将此方法的返回结果定义为类或接口。然后您可以通过该类或接口接收服务。
单例
<?php class SomeProvider { function someService(): Service { return new Service(); } }
工厂
如果您想定义工厂,请添加可变参数。
<?php class SomeProvider { function someService(...$arguments): Service { return new Service($arguments[0]); } }
依赖项
当您的服务需要其他服务时,您可以将此依赖项添加到方法参数中。
<?php class SomeProvider { function someService(ServiceBeta $beta): ServiceAlpha { return new ServiceAlpha($beta); } }
记住,参数也是服务
<?php use Moro\Container7\Parameters; class SomeProvider { function someService(Parameters $parameters): Service { return new Service($parameters->get('key')); } }
定义之后修改服务
在某些情况下,您可能希望在定义之后修改服务定义。您可以使用接收服务对象并可以返回 null 的方法。
<?php class SomeProvider { function extendService(Service $service) { $service->value = 'value'; // example } }
如果您需要替换服务实例,请使用该定义
<?php class SomeProvider { function extendService(Service $service): ?Service { return new Decorator($service); } }
您可以在这里添加依赖项,就像在工厂定义中一样。
参数
添加默认参数。
<?php use Moro\Container7\Parameters; class SomeProvider { function parameters(Parameters $parameters) { $parameters->set('key1', 'value1'); $parameters->set('key2', '%key1%'); $parameters->add('key0', ['new item']); } function someService(Parameters $parameters): Service { $service = new Service(); $service->value = $parameters->get('key2'); return $service; } }
设置参数的当前值,以替换默认值。
<?php use Moro\Container7\Container; use Moro\Container7\Parameters; $parameters = new Parameters(['key1' => 'value2']); $container = new Container($parameters); $container->addProvider(SomeProvider::class);
并使用它。
<?php $service = $container->get(Service::class); assert($service->value === 'value2');
别名
当您不能通过类或接口获取服务时,则必须为类、接口或方法定义别名。
<?php use Moro\Container7\Aliases; class SomeProvider { function someService(): Service { return new Service(); } function aliases(Aliases $aliases) { // Add alias for unique interface in provider $aliases->add('kernel', Service::class); // or you can use method name $aliases->add('kernel', 'someService'); } }
现在您可以通过别名获取服务。
<?php $service = $container->get('kernel');
标签
您可以通过为它们设置一个公共标签来按组对服务进行分组。
<?php use Moro\Container7\Tags; class SomeProvider { function tags(Tags $tags) { // Add tag for unique interface in provider $tags->add('someTag', ServiceAlpha::class); $tags->add('someTag', ServiceBeta::class); // or you can use method name $tags->add('someTag', 'getServiceAlpha'); $tags->add('someTag', 'getServiceBeta'); } }
然后获取服务的集合。
<?php $collection = $container->getCollection('someTag');
集合实现了 Iterator 接口,您可以在 foreach 中使用它。
集合操作
<?php use Moro\Container7\Container; $container = new Container(); $collection = $container->getCollection('A'); // Collection contains services with tag "A". $collection = $collection->merge('B'); // Collection contains services with tags "A" or "B". $collection = $collection->exclude('A'); // Collection contains services with tag "B" and without tag "A". $collection = $collection->merge('B')->with('C'); // The collection contains services that are marked // with "B" and "C" tags simultaneously.
配置
Container7 支持以 JSON 格式配置文件。您可以从这些文件创建提供者。
<?php use Moro\Container7\Container; use Moro\Container7\Parameters; $configuration = Parameters::fromFile('conf.json'); $container = new Container($configuration);
配置文件可以是嵌套的。
{ "@extends": [ "module1.json", "../module2.json" ] }
单例
{ "container": { "singletons": [ { "interface": "ServiceInterface", "class": "Service" } ] } }
工厂
{ "container": { "factories": [ { "interface": "ServiceInterface", "class": "Service" } ] } }
依赖项
{ "container": { "singletons": [ { "interface": "ServiceInterface", "class": "ServiceAlpha", "args": [ "@ServiceBeta" ], "properties": { "value": 1 }, "calls": [ { "method": "add", "args": [ "key", "value" ] } ] } ] } }
定义之后修改服务
{ "container": { "extends": [ { "target": "ServiceInterface", "calls": [ { "method": "add", "args": [ "key", "value" ] } ] } ] } }
如果您需要替换服务实例,请使用该定义
{ "container": { "extends": [ { "target": "ServiceInterface", "class": "Decorator", "args": [ "$target" ] } ] } }
参数、别名和标签
{ "container": { "parameters": { "key1": "value1", "key2": "%key1%" }, "singletons": [ { "aliases": ["kernel"], "tags": ["someTag"], "interface": "ServiceInterface", "class": "ServiceAlpha", "properties": { "value": "%key2%" } }, { "tags": ["someTag"], "class": "ServiceBeta" }, { "class": "Service", "args": [ "$collections[someTag]" ] }, { "class": "Service", "calls": [ { "foreach": "$collections[someTag]", "method": "add", "args": ["$item"] } ] } ] } }
动态服务
<?php use Moro\Container7\Container; use Moro\Container7\Provider; class DynamicProvider { function boot(Container $container) { $configuration = []; // ... dynamic create of configuration array ... $container->addProvider(Provider::fromConfiguration(__METHOD__, $configuration)); } }
许可
MIT 许可证 (MIT)。有关更多信息,请参阅 许可证文件。