2015-06-03 71 views
1

序言Symfony2的:依賴注入的請求依賴

我的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. 我可以使用某種代理類,轉發交互到正確的電子郵件嗎?

還是我完全在錯誤的路線?

回答

1

以供將來參考,這裏是實施Peter's answer

Custom mailer for FOSUserBundle配置:

# 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); 
    } 
}