我有示例服务:
<?php
namespace AppBundle\Service;
use AppBundle\Entity\Article;
use CompanyName\Utils\ClassFromVendor;
class DecorateArticle
{
private $customDecorator;
private $article;
public function __construct(CustomDecorator $customDecorator)
{
$this->customDecorator = $customDecorator;
}
public function setNews(Article $article)
{
$this->article = $article;
}
public function decorate() : string
{
$text = strip_tags($this->article->getBody());
$text = $this->customDecorator->doIt($text);
$classFromVendor = new ClassFromVendor();
$text = $classFromVendor->doIt($text);
return $text;
}
}
//controller:
public function showToApiAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$news = $em->getRepository('AppBundle:News')->find($request->get('id'));
$decorateArticle = $this->get('AppBundle\Service\DecorateArticle');
$decorateArticle->setNews($news);
return $decorateArticle->decorate();
}
//services.yml:
AppBundle\Service\DecorateArticle:
arguments:
$decorateArticle: '@AppBundle\Service\DecorateArticle'
public: true
此代码中的一切都运行良好,但我的团队负责人告诉我,它违反了SOLID原则。
这就是我做的原因:
<?php
namespace AppBundle\Service;
use AppBundle\Entity\Article;
use CompanyName\Utils\ClassFromVendor;
class DecorateArticle
{
private $customDecorator;
private $classFromVendor;
private $article;
public function __construct(CustomDecorator $customDecorator, ClassFromVendor $classFromVendor)
{
$this->customDecorator = $customDecorator;
$this->classFromVendor = $classFromVendor;
}
public function setNews(Article $article)
{
$this->article = $article;
}
public function decorate() : string
{
$text = strip_tags($this->article->getBody());
$text = $this->customDecorator->doIt($text);
$text = $this->classFromVendor->doIt($text);
return $text;
}
}
//controller:
public function showToApiAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$news = $em->getRepository('AppBundle:News')->find($request->get('id'));
$decorateArticle = $this->get('AppBundle\Service\DecorateArticle');
$decorateArticle->setNews($news);
return $decorateArticle->decorate();
}
//services.yml:
AppBundle\Service\DecorateArticle:
arguments:
$decorateArticle: '@AppBundle\Service\DecorateArticle'
$classFromVendor: 'CompanyName\Utils\ClassFromVendor'
public: true
但是这个抛出错误:
类型错误:参数2传递给 AppBundle \ Service \ DecorateArticle :: __ construct()必须是一个实例 of CompanyName \ Utils \ ClassFromVendor或null,给定字符串
如何将供应商类注入服务?
也许有更好的方法来做我做的事情? 我不确定我是否可以在一个类中使用services.yml和setter(setNews)中的注入。
答案 0 :(得分:0)
试试这个。
AppBundle\Service\DecorateArticle:
arguments:
decorateArticle: '@AppBundle\Service\DecorateArticle'
classFromVendor: companyName.utils.ClassFromVendor
public: true
companyName.utils.ClassFromVendor:
class: CompanyName\Utils\ClassFromVendor
public: false
我不知道decorateArticle是否有效,因为你使用相同的服务作为参数.. 我认为这是将类作为参数传递给服务的正确方法。
答案 1 :(得分:0)
在Symfony 4中,我需要将供应商类注入我的一项服务中:
jiraRestApi.ClassFromVendor:
class: JiraRestApi\Issue\IssueService
public: false
CM\Infrastructure\IssueJira\IssueJiraDbRepository:
arguments: ['@jiraRestApi.ClassFromVendor', '@parameter_bag']
public: false
您可能认为jiraRestApi.ClassFromVendor在哪里是供应商类。
我的IssueJiraDbRepository.php具有一个构造函数:
public function __construct(JiraRestApi Issue, ParameterBagInterface $params){ ...
因此,在您的情况下,我认为您必须进行service.yaml:
CompanyName.ClassFromVendor:
class: CompanyName\Utils\ClassFromVendor
public: false
AppBundle\Service\DecorateArticle:
arguments:['@CompanyName.ClassFromVendor']
public: true
记住参数中的“ @”。控制器中的构造函数应保持不变:
public function __construct(CustomDecorator $customDecorator)
{
$this->customDecorator = $customDecorator;
}
将services.yaml处理为控制器的构造函数。在那里放置的参数将用于创建控制器的实例。您说的错误是您传递了字符串而不是对象。如果您有问题,可以随时使用自动装配,在大多数情况下就足够了。请记住,service.yaml中的新条目将替换以前的条目。