Symfony2: внедрение зависимостей зависит от запроса

преамбула

Мое приложение Symfony2 будет доступно из нескольких доменов верхнего уровня. В зависимости от TLD, я хочу использовать другую почтовую программу. Однако мне не удалось динамически внедрить правильный почтовик, несмотря на множество попыток (фабрика сервисов, проход компилятора, расширение DI, «динамический псевдоним»).

Это приводит к фундаментальной реализации: вводятся зависимости до контейнер скомпилирован, запрос доступен после контейнер скомпилирован. Следовательно, нет способа сделать внедрение зависимостей зависимым от запроса (и, следовательно, все вышеупомянутые подходы потерпели неудачу).

проблема

Мне сказали никогда не тянуть зависимости, а всегда вводить их.

Чтобы проиллюстрировать это далее:

я имею

и хотите ввести правильный Swiftmailer в пользовательский почтовый сервис для FOSUserBundle (или в любой другой сервис, который нуждается в swiftmailer).

Вопрос

Как ввести правильную зависимость, если я не знаю ее, пока запрос не будет доступен?

У меня было две идеи, но я не уверен, насколько они подходят:

  1. Должен ли я вводить какой-то «Mailer Provider»? Все еще что-то вроде вытягивания зависимостей, не так ли?
  2. Могу ли я использовать какой-то прокси-класс, перенаправляющий взаимодействие на правильный адрес электронной почты?

Или я совсем не по маршруту?

1

Решение

Внедрение запроса описано в документации. Это, как говорится, я думаю, вы получите максимальную отдачу за доллар используя фабрику.

1

Другие решения

Для дальнейшего использования, вот реализация Ответ Питера:

Пользовательский почтовик для 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);
}
}
1

По вопросам рекламы [email protected]