gpt4 book ai didi

Symfony3 工厂即服务

转载 作者:行者123 更新时间:2023-12-01 09:17:15 25 4
gpt4 key购买 nike

我一直在努力解决这个问题

http://symfony.com/doc/current/service_container/factories.html

但是似乎缺少一 block 将所有这些都累到一起的部分,或者我完全错过了重点。

该示例有一个工厂类

class NewsletterManagerFactory
{
public static function createNewsletterManager()
{
$newsletterManager = new NewsletterManager();

// ...

return $newsletterManager;
}
}

然后通过服务将该工厂配置为 NewsletterManager 的工厂类和方法服务。
services:
app.newsletter_manager_factory:
class: AppBundle\Email\NewsletterManagerFactory

app.newsletter_manager:
class: AppBundle\Email\NewsletterManager
factory: 'app.newsletter_manager_factory:createNewsletterManager'

所以现在我们有一个 NewsletterManager知道 NewsletterManagerFactory 的类通过 factory: 上课 services.yml 中的参数

问题

您如何使用此配置? NewsletterManager 内部现在暴露的内容这让我可以调用 createNewsletterManager在工厂类?

据我所知,这两个服务仍然完全分开?

最佳答案

我曾经使用过这种模式。这是它的用例。

假设您有多个小部件类,即 Acme\Widget1 , Acme\Widget2 , Acme\WidgetN .

每个小部件都有一个高级实例化过程,因此您决定使用工厂。它还有一个复杂的依赖链,每个小部件都需要实例化。 IE。 Acme\Dependency1 , Acme\Dependency2 , Acme\Dependency3 .

所以你要做的是创建 Acme\WidgetFactory具有依赖关系的服务一次。然后你需要指定 Acme\WidgetFactory作为每个小部件的工厂。如果小部件实例化方式发生变化,您只需要更改一个类和一个服务定义。所有 1 到 N 小部件服务保持不变。

这是示例...

典型实现方式:

acme.widget1:
class: Acme\Widget1
factory: ['Acme\Widget1', 'create']
arguments: ['@acme.dependency1', '@acme.dependency2', '@acme.dependencyN']

acme.widget2:
class: Acme\Widget2
factory: ['Acme\Widget2', 'create']
arguments: ['@acme.dependency1', '@acme.dependency2', '@acme.dependencyN']

acme.widgetN:
class: Acme\WidgetN
factory: ['Acme\WidgetN', 'create']
arguments: ['@acme.dependency1', '@acme.dependency2', '@acme.dependencyN']

在这里,您有强烈的代码重复气味。如果你想改变一些东西,你需要做N次。

相反,这是您可以做的。
acme.widget_factory:
class: Acme\WidgetFactory
arguments: ['@acme.dependency1', '@acme.dependency2', '@acme.dependencyN']

acme.widget1:
class: Acme\Widget1
factory: ['@acme.widget_factory', createWidget]

acme.widget2:
class: Acme\Widget2
factory: ['@acme.widget_factory', createWidget]

acme.widgetN:
class: Acme\WidgetN
factory: ['@acme.widget_factory', createWidget]

代码重复消失了。

出现了小不便... 工厂不知道要实例化什么具体的类。我使用了以下技术。

我标记了每个小部件,然后在编译器传递过程中向工厂添加了额外的参数。
acme.widget_factory:
class: Acme\WidgetFactory
arguments: ['@acme.dependency1', '@acme.dependency2', '@acme.dependencyN']

acme.widget1:
class: Acme\Widget1
factory: ['@acme.widget_factory', createWidget]
tags:
- { name: acme.widget }

acme.widget2:
class: Acme\Widget2
factory: ['@acme.widget_factory', createWidget]
tags:
- { name: acme.widget }

acme.widgetN:
class: Acme\WidgetN
factory: ['@acme.widget_factory', createWidget]
tags:
- { name: acme.widget }

然后在 DependencyInjection\AcmeDemoExtension.php
class AcmeDemoExtension implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$widgets = $container->findTaggedServiceIds('acme.widget');
foreach ($widgets as $id => $tags) {
$definition = $container->getDefinition($id);
$definition->setArguments([$definition->getClass()]);
}
}
}

最后在工厂...
class AcmeWidgetFactory
{
//.....
public static function createWidget($class)
{
//.....
return new $class(/* dependencies */);
//.....
}
//.....
}

所以最后当你做 $this->get('acme.widget1')以类名作为参数的工厂方法被调用。 Factory 已经拥有了所有的依赖,并且知道类实例化的逻辑。所以它完成了所有工作并返回所需的小部件实例。

关于Symfony3 工厂即服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41185608/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com