acelaya/zsm-annotated-services

此包已被废弃且不再维护。未建议替代包。

一个组件,用于定义如何通过注解使用 Zend\ServiceManager 进行依赖注入

v1.0.2 2016-12-23 19:39 UTC

This package is auto-updated.

Last update: 2024-01-26 08:23:50 UTC


README

Build Status Code Coverage Scrutinizer Code Quality Latest Stable Version Total Downloads License

如果你厌倦了在项目中定义大量工厂,只是为了从 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 对象。然后,它将使用点分隔的其余部分作为数组中的嵌套键,并最终获取最后一个值并将其注入到服务中。