Symfony2:依赖于请求的依赖注入

时间:2015-06-03 12:29:13

标签: php symfony dependency-injection proxy-classes

序言

我的Symfony2应用程序将从多个顶级域名(TLD)访问。根据TLD,我想使用不同的swiftmailer邮件程序。然而,尽管尝试了多种方法(服务工厂,编译器传递,DI扩展,"动态别名"),但我无法动态注入正确的邮件程序。

这导致了一个基本的实现:在编译容器之前注入依赖关系,在编译容器之后可以获得请求。因此,没有办法使依赖注入依赖于请求(因此所有上述方法都失败了)。

问题

我被告知永远不要拉依赖,但总要注入它们。

进一步说明:

我有

  • three swiftmailers:mailer_en,mailer_de,mailer_ie和
  • 三个域:domain.co.uk,domain.de和domain.ie

并希望将正确的swiftmailer注入custom mailer service for FOSUserBundle(或任何其他需要swiftmailer的服务)。

问题

如果在请求可用之前我不知道,我该如何注入正确的依赖项?

我有两个想法,但不确定它们的适用性:

  1. 我应该注射某种"邮件提供商"?仍然有点依赖,不是吗?
  2. 我可以使用某种代理类,将交互转发给正确的电子邮件吗?
  3. 或者我完全走错了路线?

2 个答案:

答案 0 :(得分:1)

注入请求is covered in the documentation。话虽如此,我认为你会获得最大的收益by using a factory

答案 1 :(得分:1)

以下是Peter's answer 实施:

Custom mailer for FOSUserBundle config:

# app/config/config.yml

fos_user:
    # ...
    service:
        mailer: acme.mailer

# src/Acme/UserBundle/config/services.xml

<service id="acme.mailer.factory" class="Acme\UserBundle\Service\TwigSwiftMailerFactory" public="false">
    <call method="setContainer">
        <argument type="service" id="service_container" />
    </call>
</service>

<service id="acme.mailer" class="TwigSwiftMailer">
    <factory service="propeo_user.mailer.factory" method="createTwigSwiftMailer" />
    <argument type="service" id="acme.mailer_name_provider" />
    <argument type="service" id="router" />
    <argument type="service" id="twig" />
    <argument type="collection">
        <argument key="template" type="collection">
            <argument key="confirmation">%fos_user.registration.confirmation.template%</argument>
            <argument key="resetting">%fos_user.resetting.email.template%</argument>
        </argument>
    </argument>
</service>

以及工厂类:

# Acme/UserBundle/Service/TwigSwiftMailerFactory

class TwigSwiftMailerFactory extends ContainerAware
{
    private function getContainer()
    {
        if(!($this->container instanceof ContainerInterface)) {
            throw new \RuntimeException('Container is missing');
        }
        return $this->container;
    }

    public function createTwigSwiftMailer(MailerNameProvider $mailerNameProvider, UrlGeneratorInterface $router, \Twig_Environment $twig, array $parameters)
    {
        $container = $this->getContainer();
        $name = $mailerNameProvider->getMailerName(); // returns mailer name, e.g. mailer_en

        $mailer = $container->get(
            sprintf('swiftmailer.mailer.%s', $name ? $name : 'default')
        );

        $parameters['from_email']['confirmation'] =
            $parameters['from_email']['resetting'] =
                $container->getParameter(
                    sprintf('swiftmailer.mailer.%s.sender_address', $name ? $name : 'default')
                )
        ;

        return new TwigSwiftMailer($mailer, $router, $twig, $parameters);
    }
}