mtymek/blast-reflection-factory

Laminas ServiceManager的通用自动绑定工厂。

2.1 2022-07-08 14:07 UTC

This package is auto-updated.

Last update: 2024-09-08 18:52:59 UTC


README

Build Status

Laminas ServiceManager的通用自动绑定工厂。

简介

为Laminas ServiceManager编写工厂是一个枯燥且重复的任务。典型的服务将使用构造函数注入来消耗一个或多个依赖项

class Mailer
{
    public function __construct(MailTransportInterface $transport, MailRenderer $renderer)
    {
      // ...
    }
}

工厂将看起来像这样

class MailerFactory
{
    public function __invoke(ContainerInterface $container)
    {
        return new Mailer(
            $container->get(MailTransportInterface::class),
            $container->get(MailRenderer::class)
        );
    }
}

在典型应用中,你最终会有多个工厂,它们只是拉取一些服务并创建新对象。ReflectionFactory可以为你处理这种情况 - 它使用Reflection扫描构造函数中的参数类型,并根据这些信息实例化新对象。

安装

使用Composer安装此包

$ composer require mtymek/blast-reflection-factory

用法

安装此包后,你所要做的就是告诉ServiceManager使用ReflectionFactory来创建你的服务。

Laminas Mezzio应用的配置示例

use Blast\ReflectionFactory\ReflectionFactory;

return [
    'dependencies' => [
        'factories' => [
            // use normal factory for classes that require complex instantiation 
            SmtpMailTransport::class => SmtpMailTransportFactory::class,
             
            // use ReflectionFactory for auto-wiring
            MailRenderer::class => ReflectionFactory::class,
            Mailer::class => ReflectionFactory::class,
        ],
        'aliases' => [
            MailTransportInterface::class => SmtpMailTransport::class,
        ],
    ]
];

缓存

自动绑定是一个昂贵的操作,所以ReflectionFactory允许将结果存储到磁盘以供以后重用

\Blast\ReflectionFactory\ReflectionFactory::enableCache('data/cache/reflection-factory.cache.php');

如果你使用的是Zend Expressive Skeleton应用程序,那么在config/container.php中启用此缓存将是一个不错的选择。

预热缓存

当服务第一次从容器中提取时,缓存文件会自动更新。当你的应用程序在高负载下运行时,这可能会导致竞争条件。为了避免这种情况,应在部署阶段预热缓存。最简单的方法是遍历所有配置的工厂,从容器中提取每个服务。

基于Mezzio Skeleton应用程序的示例脚本

<?php
// warmup-reflection-factory-cache.php

chdir(dirname(__DIR__));
require 'vendor/autoload.php';

/** @var \Interop\Container\ContainerInterface $container */
$container = require 'config/container.php';

$config = require 'config/config.php';
foreach ($config['dependencies']['factories'] as $type => $factory) {
    $container->get($type);
}

限制

ReflectionFactory仅适用于所有依赖项都通过构造函数注入的典型场景。所有这些都必须是类型提示的 - 否则,ReflectionFactory将无法解析它们。尽管存在此限制,但此库仍可让您减少需要编写的工厂数量。

不支持(且不会支持)的内容

  • 标量值注入
  • setter注入