[英]Symfony Tagged Service vs Factory
我是Symfony2的新手,有点困惑。 抱歉,这个问题听起来很傻。
根据上述链接中的文档,我可以发现的差异是:
对于标记服务:
您需要编写一个编译器遍历,然后为每个服务定义一个标签。
然后编写一个工厂(任何类。是否应该将其称为工厂?),它将从编译器传递中获取所有带标记的服务的对象。 还要在此处创建一个getter方法,该方法将根据某些条件返回对象。
如果使用工厂创建服务,则只能创建一个服务,并且通过调用静态方法将其对象返回给您。
因此,我想,在加标签的服务中,您可以从许多服务中进行选择,并且如果是按工厂创建服务,则只能创建一个服务。 我认为标记服务已经为工厂服务。 当工厂只能创建一个对象时,为什么需要工厂服务? 可能是我有一个误解,但是标记服务更好,因为编译器遍历在缓存预热时运行,并且标记服务本身存储在那里,因此速度会更快。 但是,服务也被缓存,因此应该没有太大的区别。 但是我不确定这种概念是否正确。
请让我理解两者的概念并使我感到开明。
工厂服务和标记服务具有完全不同的角色。 我将尝试通过示例向您说明一些您可能想使用其中一种的常见情况。
当服务容器中没有构建服务所需的某些参数时,或者在实例化服务之前需要进行一些准备时,通常使用它。 Symfony将自动检查您的服务是否具有自己的工厂,或是否直接根据容器参数构造。
您有处理PayPal付款的服务。 要构建它,您需要在您的PayPal凭据和API端点URL中传递它。
class PayPalPaymentService
{
// ...
public function __construct(PayPalCredentials $credentials, $apiEndpoint)
{
// ...
}
// ...
}
这对您来说效果很好,但是您意识到需要拥有两个环境: Live和Sandbox 。 根据您所处的环境,您的凭据和API终结点URL都不同。
Symfony有两种方法可以为您处理此问题,但其中一种方法是通过工厂服务 :您创建一个工厂,该工厂将根据您当前的本地环境实例化PayPalPaymentService 。
class PayPalPaymentServiceFactory
{
const SANDBOX_ENDPOINT = '...';
const LIVE_ENDPOINT = '...';
private $livePublic;
// ...
public function __construct($livePublic, $liveSecret, $sandboxPublic, $sandboxSecret, $kernelEnvironment)
{
$this->livePublic = $livePublic;
// ...
}
public function create()
{
if ('prod' === $kernelEnvironment) {
$credentials = new PayPalCredentials($this->livePublic, $this->liveSecret);
} else {
$credentials = new PayPalCredentials($this->sandboxPublic, $this->sandboxSecret);
}
$url = 'prod' === $kernelEnvironment ? self::LIVE_ENDPOINT : self::SANDBOX_ENDPOINT;
return new PayPalPaymentService($credentials, $url);
}
}
现在,无论何时注入PayPalPaymentService,容器都会首先要求PayPalPaymentServiceFactory创建它,然后注入它。
这些是完全不同的故事。 标记服务在整个Symfony代码库中使用:用于FormType,Twig扩展,验证器等。标记服务的概念是一种非常强大的扩展机制。 它允许您将服务标记为用于特定目的的服务。 就像我说的那样,Symfony代码库中已经有它们的示例,但是下面是一个非常简化的示例,以了解您可以使用它们做什么:
您在电子商店中有付款,并且有受支持的付款处理者列表。 每个付款处理方都有其自己的结帐页面。 因此,您决定使其模块化,并让其他人为其创建新的付款处理程序。
在购物车页面上,您需要显示指向所有可用的付款处理程序结帐页面的链接,为此,您需要提供一项服务,该服务为您提供所有可用的结帐链接:
class CheckoutLinksProvider
{
/**
* @var ProcessorAdapter[]
*/
private $adapters;
public function registerProcessor(ProcessorAdapter $adapter)
{
$this->adapters = $adapter;
}
public function getCheckoutLinks()
{
$links = [];
foreach ($this->adapters as $adapter) {
$links[] = $adapter->getCheckoutLink();
}
return $links;
}
}
interface ProcessorAdapter
{
/**
* @return string Checkout URL link
*/
public function getCheckoutLink();
// ...
}
现在,任何人都可以实现ProcessorAdapter
并将其作为捆绑包在Github上共享! 他们要做的只是用您确定的标记来标记ProcessorAdapter
实现,例如:“ my_eshop_processor_adapter”。
现在,在您的核心E-shop系统编译器传递中,您可以选择所有ProcessorAdapter
实现并将其注册到CheckoutLinksProvider
服务中。 瞧! 您有一个完全模块化的付款系统! 任何人都可以创建对自定义处理器的支持,您只需下载其捆绑包并将其注册到内核中,就会出现结帐链接!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.