Symfony 3:如何根据某些运行时变量动态注入服务
Symfony 3: How can I inject a service dynamically depending on some runtime variable
假设我有以下 interface/concrete 类:
interface EmailFormatter
class CvEmailFormatter implements EmailFormatter
class RegistrationEmailFormatter implements EmailFormatter
class LostPasswordEmailFormatter implements EmailFormatter
然后我有一个自定义 'mailer' 服务,该服务从我的控制器操作中调用以发送电子邮件。
根据发送的电子邮件类型,我有哪些选项可以将 EmailFormatter 的正确实现注入到我的邮件程序服务中?
我会创建一个服务,在运行时选择正确的格式化程序,或者是某种工厂,或者如果你的格式化程序有依赖关系,也许是你从容器中注入格式化程序的服务。像这样:
class MailController extends AbstractController
{
private $mailer;
private $mailFormatterSelector;
public function __construct(...) { ... }
public function someAction()
{
// Do stuff ...
if (...some condition) {
$formatter = $this->mailFormatterSelector->getRegisterMailFormatter();
} else {
$formatter = $this->mailFormatterSelector->getLostPasswordEmailFormatter();
}
$mailer->sendEmail($formatter);
// Do more stuff ...
}
}
class MailFormatterSelector()
{
private $registrationFormatter;
public function __construct(EmailFormatter $registrationFormatter, ...)
{
$this->registrationFormatter = $registrationFormatter;
...
}
public function getRegisterMailFormatter(): EmailFormatter
{
return $this->registrationFormatter;
}
// ...
}
或者,如果您必须在构造期间将格式化程序传递到您的邮件程序中,您还可以创建多个具有不同别名的不同设置实例,然后根据需要将它们注入到服务和控制器中,如下所示:
# config/services.yaml
mailer1:
class: MyMailler
arguments:
$formatter: '@formatter1'
mailer2:
class: MyMailler
arguments:
$formatter: '@formatter2'
MyMailController:
arguments:
$mailer: '@mailer2'
然后在您的控制器或操作中,您可以通过以下方式传入 mailer1、mailer2、...(可能使用更好的名称)。
假设我有以下 interface/concrete 类:
interface EmailFormatter
class CvEmailFormatter implements EmailFormatter
class RegistrationEmailFormatter implements EmailFormatter
class LostPasswordEmailFormatter implements EmailFormatter
然后我有一个自定义 'mailer' 服务,该服务从我的控制器操作中调用以发送电子邮件。
根据发送的电子邮件类型,我有哪些选项可以将 EmailFormatter 的正确实现注入到我的邮件程序服务中?
我会创建一个服务,在运行时选择正确的格式化程序,或者是某种工厂,或者如果你的格式化程序有依赖关系,也许是你从容器中注入格式化程序的服务。像这样:
class MailController extends AbstractController
{
private $mailer;
private $mailFormatterSelector;
public function __construct(...) { ... }
public function someAction()
{
// Do stuff ...
if (...some condition) {
$formatter = $this->mailFormatterSelector->getRegisterMailFormatter();
} else {
$formatter = $this->mailFormatterSelector->getLostPasswordEmailFormatter();
}
$mailer->sendEmail($formatter);
// Do more stuff ...
}
}
class MailFormatterSelector()
{
private $registrationFormatter;
public function __construct(EmailFormatter $registrationFormatter, ...)
{
$this->registrationFormatter = $registrationFormatter;
...
}
public function getRegisterMailFormatter(): EmailFormatter
{
return $this->registrationFormatter;
}
// ...
}
或者,如果您必须在构造期间将格式化程序传递到您的邮件程序中,您还可以创建多个具有不同别名的不同设置实例,然后根据需要将它们注入到服务和控制器中,如下所示:
# config/services.yaml
mailer1:
class: MyMailler
arguments:
$formatter: '@formatter1'
mailer2:
class: MyMailler
arguments:
$formatter: '@formatter2'
MyMailController:
arguments:
$mailer: '@mailer2'
然后在您的控制器或操作中,您可以通过以下方式传入 mailer1、mailer2、...(可能使用更好的名称)。