我在正确安排服务方面遇到问题。我想创建一个生成器,感谢提供者,它将通过工厂方法创建相应的生成器对象。在我看来,它或多或少看起来像这样:
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;
}
如果我理解正确,你应该使用标记迭代器。我还没有找到一个很好的例子/文章。所以这是一个未经测试的例子。但是 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');
}
}
我想我已经解决了我的问题。我稍微改变了这个概念。我相应地划分了服务,现在它将服务注入控制器中。注入服务时,我为 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 '';
}