У меня класс ff:
namespace App\Component\Notification\RealTimeNotification;
use App\Component\Notification\NotificationInterface;
class EmailNotification implements NotificationInterface
{
private $logNotification;
private $mailer;
private $engine;
// This will appear on From field on Email.
private $mailerFrom;
public function __construct(LogNotification $logNotification, \Swift_Mailer $mailer, \Twig_Environment $twig, string $from)
{
$this->logNotification = $logNotification;
$this->mailer = $mailer;
$this->twig = $twig;
$this->mailerFrom = $mailerFrom;
}
public function send(array $options): void
{
// Resolve options
$this->resolveOptions($options);
$sendTo = $options['sendTo'];
$subject = $options['subject'];
$template = $options['template'];
$data = $options['data'];
$body = $this->createTemplate($template, $data);
$this->sendEmail($sendTo, $subject, $body);
}
protected function sendEmail($sendTo, $subject, $body): void
{
dump($this->mailerFrom);
$message = (new \Swift_Message())
->setSubject($subject)
->setFrom($this->mailerFrom)
->setTo($sendTo)
->setBody($body, 'text/html')
;
$this->mailer->send($message);
}
protected function createTemplate($template, $data): string
{
return $this->twig->render($template, $data);
}
protected function resolveOptions(array $options): void
{
}
protected function createLog(array $email): void
{
$message = 'Email has been sent to: ' . $email;
$this->logNotification->send([
'message' => $message,
]);
}
}
Я попытался вручную связать все аргументы следующим образом:
# Notification
app.log_notification:
class: App\Component\Notification\RealTimeNotification\LogNotification
app.email_notification:
class: App\Component\Notification\RealTimeNotification\EmailNotification
decorates: app.log_notification
decoration_inner_name: app.log_notification.inner
arguments:
$logNotification: '@app.log_notification.inner'
$mailer: '@mailer'
$twig: '@twig'
$from: '%mailer_from%'
Однако когда я запускаю приложение, оно выдает исключение:
Cannot autowire service "App\Component\Notification\RealTimeNotification\EmailNotification": argument "$from" of method "__construct()" must have a type-hint or be given a value explicitly
Почему происходит это событие?
Спасибо!
@Cerad, ты прав. Вот как я это сделал. Спасибо!




Автосоединение работает только тогда, когда ваш аргумент является объектом. Но если у вас есть скалярный аргумент (например, строка), его нельзя автоматически подключить: Symfony выдаст явное исключение.
Вы должны Аргументы подключения вручную и явно настроить службу, например:
# config/services.yaml
services:
# ...
# same as before
App\:
resource: '../src/*'
exclude: '../src/{Entity,Migrations,Tests}'
# explicitly configure the service
App\Updates\SiteUpdateManager:
arguments:
$adminEmail: '[email protected]'
Thanks to this, the container will pass [email protected] to the $adminEmail argument of __construct when creating the SiteUpdateManager service. The other arguments will still be autowired.
Надеюсь на эту помощь
Ответ @Matteo великолепен! Вы даже можете отбросить определение службы и делегировать привязка параметровначиная с Smyfony 3.4 + / 2018 +:
# config/services.yaml
services:
_defaults:
bind:
$adminEmail: '[email protected]'
# same as before
App\:
resource: '../src/*'
Хотите больше примеров и логики? Найдите здесь: https://www.tomasvotruba.cz/blog/2018/01/22/how-to-get-parameter-in-symfony-controller-the-clean-way/#change-the-config
Мне не нужно использовать app.email_notification, вместо этого я использую полное имя класса.
Нет, здесь нет аргументов. Это просто способ еще больше сократить объем написания. Да, вы можете использовать подсказку напрямую. Именованный сервис не нужен, начиная с Symfony 2.8 и autowiring.
Это потому, что вы пытаетесь внедрить свое EmailNotification в еще одну службу, используя подсказку типа EmailNotification. Таким образом, autowire ищет в контейнере идентификатор службы, соответствующий имени класса. Он не будет автоматически использовать app.email_notification. Таким образом, он пытается создать новую службу и терпит неудачу на скаляре. Если вы используете autowire, вам больше не нужны идентификаторы служб, такие как app.email_notification. Просто используйте имя класса. И если вы действительно хотите сохранить свой идентификатор, добавьте псевдоним. Все это задокументировано. Также куча вопросов на ту же тему.