paysera /lib-dependency-injection
为Symfony依赖注入组件提供辅助类
1.4.0
2023-11-24 12:04 UTC
Requires
- php: ^7.0 | ^8.0
- symfony/config: ^2.3|^3.0|^4.0|^5.0|^6.0
- symfony/dependency-injection: ^2.3|^3.0|^4.0|^5.0|^6.0
Requires (Dev)
- phpunit/phpunit: ^6.5 | ^8.0 | ^9.0
This package is auto-updated.
Last update: 2024-09-24 14:03:52 UTC
README
这是什么?
为简化与Symfony依赖注入组件的集成提供额外功能。
包含用于注册带有标签的服务以及某些其他服务的编译器传递 - 无需在每种情况下都编写自定义类。
安装
composer require paysera/lib-dependency-injection
基本功能
将带有标签的服务注册到其他服务。可选地传递标签的属性。
class SomeBundle extends Bundle { public function build(ContainerBuilder $container) { $container->addCompilerPass(new AddTaggedCompilerPass( 'some_bundle.registry', // ID of service to modify 'my_provider', // name of tag to search for 'addProvider', // method to call on modified service [ // this parameter is optional and defines attributes to pass from tag 'key', 'theme' => 'default', // attribute with default value 'optional', ] )); } }
class Registry { // first - tagged service. Others (optional) in the order as they come in the attributes array public function addProvider(ProviderInterface $provider, $key, $theme, $optional = null) { $this->providers[$key] = $provider; // or whatever } }
<service id="some_bundle.registry" class="Acme\Registry"> <argument>Any arguments service might have</argument> <!-- Such comment is optional here, but highly recommended for easier debugging: --> <!-- Calls addProvider with each service tagged with my_provider --> </service> <service id="awesome_provider" class="Acme\AwesomeProvider"> <tag name="my_provider" key="awesome"/> </service> <service id="nice_provider" class="Acme\NiceProvider"> <tag name="my_provider" key="nice" theme="not a default one"/> </service> <service id="superb_provider" class="Acme\SuperbProvider"> <tag name="my_provider" key="superb" optional="leave theme as default, overwrite optional"/> <!-- Same service can have several tags, method will be called for each one of them --> <tag name="my_provider" key="superb_dark" theme="dark"/> </service>
使用优先级
有时我们需要通过预定义的优先级调用带有标签的服务的方法。我们可以在服务本身中进行优先级排序,但这会使代码重复,并且不如编译时排序快 - 在运行时不需要对任何东西进行排序。
在注册编译器传递时应该启用优先级。它通过 priority
属性提供。优先级越低,调用越早。如果没有提供优先级,则默认为 0
。
class SomeBundle extends Bundle { public function build(ContainerBuilder $container) { $container->addCompilerPass((new AddTaggedCompilerPass( 'some_bundle.registry', // ID of service to modify 'my_provider', // name of tag to search for 'addProvider', // method to call on modified service ['key', 'theme' => 'default', 'optional'], ))->enablePriority()); // attribute name can be passed here, defaults to `priority` } }
<service id="awesome_provider" class="Acme/AwesomeProvider"> <tag name="my_provider" key="awesome"/> </service> <service id="nice_provider" class="Acme/NiceProvider"> <tag name="my_provider" key="nice" priority="-1" theme="dark"/> <tag name="my_provider" key="fallback" priority="9001" optional="optional param"/> </service> <service id="another_provider" class="Acme/AnotherProvider"> <tag name="my_provider" key="another"/> </service>
解析为
// priority -1 - smallest: $registry->addProvider($niceProvider, 'nice', 'dark'); // priority defaults to 0, called in the order as registered: $registry->addProvider($awesomeProvider, 'awesome', 'default'); $registry->addProvider($anotherProvider, 'another', 'default'); // priority is over 9000: $registry->addProvider($awesomeProvider, 'fallback', 'default', 'optional param');
调整性能
当通过方法调用添加许多服务时,所有这些服务都需要在收集器服务实例化时创建。如果服务数量很多,这可能会变得麻烦。
这就是为什么你可以配置一些选项来使用,而不仅仅是传递服务
lazy_service
- 正常传递服务,但标记所有服务为懒加载。在大多数情况下,这使生产环境更快,但在开发中可能会相当慢,因为每次修改这些服务(甚至是代码本身)时,容器都必须重建;id
- 仅传递服务的ID,同时使带有标签的服务公开。这要求你将container
注入到收集器中,并在需要时通过ID获取服务。
class SomeBundle extends Bundle { public function build(ContainerBuilder $container) { $container->addCompilerPass((new AddTaggedCompilerPass( 'some_bundle.registry', // ID of service to modify 'my_provider', // name of tag to search for 'addProvider', // method to call on modified service ['key', 'theme' => 'default', 'optional'], ))->setCallMode(AddTaggedCompilerPass::CALL_MODE_ID)); } }
class Registry { private $container; public function addProvider(string $providerId, $key, $theme, $optional = null) { $this->providers[$key] = $providerId; } private function getProvider(string $key) { return $this->container->get($this->providers[$key]); } // ... }
语义版本控制
这个库遵循语义版本控制。
有关API中可以更改和不能更改的基本信息的详细信息,请参阅Symfony BC规则。
运行测试
composer update
composer test
贡献
请随意创建问题并提供拉取请求。
您可以使用以下命令修复任何代码风格问题
composer fix-cs