带有工厂方法的生成器

问题描述 投票:0回答:2

我在正确安排服务方面遇到问题。我想创建一个生成器,感谢提供者,它将通过工厂方法创建相应的生成器对象。在我看来,它或多或少看起来像这样:

API 请求提供者 -> GeneratorController::generate -> 工厂方法 -> Generator 类服务

我想使用twig生成pdf文件,但是我的ContainerInterface有问题。恐怕我的操作概念不正确。有谁能告诉我我的方向是否正确?

我想制作一个通过提供者和生成器类创建的 pdf 生成器。

发电机控制器

public function generate($provider, Request $request): Response
{
    $generator = $this->factory->createGenerator($provider);
    $content = json_decode($request->getContent(), true);
    $generator->generate($content['params']);
    
    return new JsonResponse($generator->getData());
}

发电机工厂

class GeneratorFactory
{
    public function createGenerator($generator): Generator
    {
        $generatorName = "App\\Generators\\" . ucwords($generator) . "\\Generator";

        if (!class_exists($generatorName)) {
            throw new \Exception("We dont find genarator with name: " . $generator);
        }

        return new $generatorName;
    }
}

工厂发电机

 public function __construct()
    {
        $this->object = new GeneratorObject;
        $this->validator = new Validator;
        $this->service = new PdfService();
    }
    public function generate(array $params): void
    {
        $valided = $this->validator->Validate($params);
        if (!$valided) {
            throw new Exception("Invalid parameters", 1);
        }
        $this->setDataToObject($params);
        $pdf = $this->service->createPdf($this->object);
        $this->data = $pdf;
    }

pdf 服务

public function createPdf(GeneratorObject $pdfObject): string
{
    $url = '';
    $html = $this->templating->render('pdf/index.html.twig',[$pdfObject]);

    return $url;
}
php symfony factory-method
2个回答
0
投票

如果我理解正确,你应该使用标记迭代器。我还没有找到一个很好的例子/文章。所以这是一个未经测试的例子。但是 tagged iterator 是获取更多信息的关键字。

对于 #[TaggedIterator] 和 #[AutoconfigureTag],您至少需要 PHP 8 和 Symfony 5.4。

<?php

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag;
use Symfony\Component\DependencyInjection\Attribute\TaggedIterator;

#[AutoconfigureTag('app.custom_generator_tag')]
interface GeneratorInterface
{
    public function support(string $format): bool;
    public function generate(): string;
}

abstract class GeneratorAbstract implements GeneratorInterface
{
    public function support(string $format): bool
    {
        return strtoupper($format) === $this::FORMAT;
    }
}

class PdfGenerator extends GeneratorAbstract
{
    public const FORMAT = 'PDF';

    public function __construct(/* autowire services */) { }

    public function generate(): string
    {
        return 'pdf file';
    }
}

class WordGenerator extends GeneratorAbstract
{
    public const FORMAT = 'WORD';

    public function __construct(/* autowire services */) { }

    public function generate(): string
    {
        return 'word file';
    }
}

class GeneratorFactory
{
    /**
     * @var GeneratorInterface[]
     */
    private array $generators;

    public function __construct(#[TaggedIterator('app.custom_generator_tag')] $generators)
    {
        $this->generators = $generators;
    }

    public function generate(string $format): string
    {
        foreach ($this->generators as $generator) {
            if ($generator->support($format)) {
                return $generator->generate();
            }
        }

        throw new \Exception('Generator not found');
    }
}

class Generatorcontroller extends AbstractController
{
    public function __construct(private GeneratorFactory $generatorFactory) {}

    public function generateAction()
    {
        return $this->generatorFactory->generate('pdf');
    }
}

0
投票

我想我已经解决了我的问题。我稍微改变了这个概念。我相应地划分了服务,现在它将服务注入控制器中。注入服务时,我为 twig 做了一个自动加载,并将其设置为从工厂方法创建的对象的变量。现在看起来像这样

控制器

public function generate($provider, Request $request, GeneratorFactory $factory): Response
{
    $generator = $factory->createGenerator($provider);
    $factory->setTwig($generator);
    $content = json_decode($request->getContent(), true);
    $generator->generate($content['params']);

    return new JsonResponse($generator->getData());
}

工厂方法

public function __construct(Environment $twig)
{
    $this->twig = $twig;
}

工厂物体

/**
 * generate
 *
 * @param  array $params
 * @return void
 */
public function generate(array $params): void
{
    $valided = $this->validator->Validate($params);
    if (!$valided) {
        throw new Exception("Invalid parameters", 1);
    }
    $this->setDataToObject($params);
    $pdf = $this->createPdf($this->object);
    $this->data = $pdf;
}
/**
 * createPdf
 *
 * @param  object $params
 * @return string
 */
private function createPdf(object $params): string
{
    $pdfHtml = $this->twig->render('pdf/cv.html.twig',[$params]);

    return '';
}
© www.soinside.com 2019 - 2024. All rights reserved.