acelaya / zsm-annotated-services
一个组件,用于定义如何通过注解使用 Zend\ServiceManager 进行依赖注入
Requires
- php: ^5.6 || ^7.0
- doctrine/annotations: ^1.2
- zendframework/zend-servicemanager: ^2.2 || ^3.0
Requires (Dev)
- doctrine/cache: ^1.6
- phpunit/phpunit: ^4.7
- squizlabs/php_codesniffer: ^2.5
Suggests
- doctrine/cache: To cache the result of processing the annotations and speed-up your application
This package is auto-updated.
Last update: 2024-01-26 08:23:50 UTC
README
如果你厌倦了在项目中定义大量工厂,只是为了从 ServiceManager 中获取一些依赖项并创建一个新的服务实例,尝试这个。
这是一个组件,允许通过注解定义如何使用 Zend\ServiceManager 进行依赖注入。
重要!虽然我会继续维护这个项目并提供错误修复,但我建议你使用自 v3.2 版本以来包含在 ServiceManager 包中的
ConfigAbstractFactory
。
安装
使用 composer 安装此组件。
composer require acelaya/zsm-annotated-services
基本用法
传统流程是,你需要为每个新服务创建一个工厂。也许有时你可以重用某些工厂或抽象工厂,但这不是常见的情况。
namespace Acelaya; use Interop\Container\ContainerInterface; class MyFactory { public funciton __invoke(ContainerInterface $container, $requestedName) { $foo = $container->get(Foo::class); $bar = $container->get('bar'); return new MyService($foo, $bar); } }
使用此组件,你只需在你的服务构造函数中添加一个简单的注解,指定需要从 ServiceManager 中获取并注入的服务。
namespace Acelaya; use Acelaya\ZsmAnnotatedServices\Annotation\Inject; class MyService { /** * @Inject({Foo::class, "bar"}) */ public function __construct($foo, $bar) { // [...] } // [...] }
然后,使用提供的工厂之一注册该服务(有一个工厂与 Zend\ServiceManager 2 一起使用,另一个与 Zend\ServiceManager 3 一起使用)
use Acelaya\MyService; use Acelaya\ZsmAnnotatedServices\Factory\V3\AnnotatedFactory; use Zend\ServiceManager\ServiceManager; $sm = new ServiceManager([ 'factories' => [ MyService::class => AnnotatedFactory::class, ], ]);
如果你使用的是 v2 ServiceManager,只需将 Acelaya\ZsmAnnotatedServices\Factory\V3\AnnotatedFactory
替换为 Acelaya\ZsmAnnotatedServices\Factory\V2\AnnotatedFactory
。
缓存
这看起来很酷,但处理注解需要时间。如果你使用这种方法与多个服务一起使用,你会看到应用程序的性能下降。
这就是为什么这个库允许使用 Doctrine\Cache 适配器来缓存注解处理的结果。
首先安装缓存组件。
composer require doctrine/cache
然后注册另一个服务,该服务返回一个 Doctrine\Common\Cache\Cache
实例,键为 Acelaya\ZsmAnnotatedServices\Factory\AbstractAnnotatedFactory::CACHE_SERVICE
(或只是 "Acelaya\ZsmAnnotatedServices\Cache",这是常量的值)。
通过这样做,你的注解将被处理和缓存,从而提高后续请求的性能。
数组和 ArrayAccess 服务的点表示法
当你需要注入包含数组或 ArrayAccess 对象的服务的一部分时,你可以使用点表示法,其中第一部分是服务名称,其余部分是获取数组的键。
例如,想象这个服务规范
use Acelaya\MyService; use Acelaya\ZsmAnnotatedServices\Factory\V3\AnnotatedFactory; use Zend\ServiceManager\ServiceManager; $sm = new ServiceManager([ 'services' => [ 'config' => [ 'mail' => [ 'smtp' => [ // [...] ], 'from' => 'foo@bar.com', 'subject' => 'Welcome!', ], 'logger' => [ 'file' => '/var/log/my_log.log' ], ], ], 'factories' => [ MyService::class => AnnotatedFactory::class, ], ]);
以及这个带有 @Inject
注解的服务
namespace Acelaya; use Acelaya\ZsmAnnotatedServices\Annotation\Inject; class MyService { /** * @Inject({"config.mail.from"}) */ public function __construct($from) { // The value of $from will be 'foo@bar.com' } }
可注入的服务由 config.mail.from 定义。在这种情况下,AnnotatedFactory
将假定服务名称为 config,并且它包含一个关联数组或 ArrayAccess 对象。然后,它将使用点分隔的其余部分作为数组中的嵌套键,并最终获取最后一个值并将其注入到服务中。