aeviiq/factory

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

服务工厂组件

v3.2.1 2021-06-28 07:50 UTC

This package is auto-updated.

Last update: 2022-10-17 09:29:41 UTC


README

原因

为了使您能够快速创建基于服务的工厂,而无需在工厂外部进行任何配置,因为工厂本身总是知道它将返回什么,因此“需要”这样做。当与 Symfony 自动装配功能结合使用时,这尤其有用,因为您只需要 getTargetInterface() 方法,就可以自动完成所有操作。

安装

composer require aeviiq/factory
Symfony >= 4
// src/Kernel.php
namespace App;

use Aeviiq\Factory\FactoryCompilerPass;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;

class Kernel extends BaseKernel
{
    use MicroKernelTrait;

    // ...

    protected function build(ContainerBuilder $container): void
    {
        $container->addCompilerPass(new FactoryCompilerPass());
    }
}
Symfony < 4
// src/AppBundle/AppBundle.php
namespace AppBundle;

use Aeviiq\Factory\FactoryCompilerPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;

class AppBundle extends Bundle
{
    public function build(ContainerBuilder $container)
    {
        parent::build($container);

        $container->addCompilerPass(new FactoryCompilerPass());
    }
}

声明

final class EncoderFactory extends AbstractServiceFactory
{
    public function getEncoder(User $user): Encoder
    {
        // getOneBy ensures 1, and only 1 encoder is returned. 
        // In case multiple encoders (or none) are found, a LogicException will be thrown.
        // In case the result is optional, you could use the getOneOrNullBy().
        return $this->getOneBy(static function (Encoder $encoder) use ($user) {
            return $encoder->supports($user);
        });
    }

    protected function getTargetInterface(): string
    {
        // All services with this interface will automatically be wired to the factory 
        // without needing any additional service configuration.
        // Using autowire these few lines are all you would need to implement your factory.
        return Encoder::class;
    }
}

用法

final class Foo
{
    /**
     * @var FactoryInterface
     */
    private $encoderFactory;

    public function __construct(FactoryInterface $encoderFactory)
    {
        $this->encoderFactory = $encoderFactory;
    }

    public function authenticateUser(User $user): void
    {
        // ...
        $encoder = $this->encoderFactory->getEncoder($user);
        if (!$encoder->isValidPassword($user->getPassword, $presentedPassword, $user->getSalt())) {
            // ...
        }
        // ...
        
    }
}