I can’t get my Mailer working when creating a service.
I’ve been following a few tutorials.
I’ve been trying to inject my dependencies but there is no way to get my $this->container->render()
working
I’m getting the following error message
ServiceNotFoundException: The service "App\Services\Mailer" has a dependency on a non-existent service "templating".
What would be a good way to inject the templating service in my Mailer service? I know this is called dependency injection but I can’t have it work properly.
I tried to follow this but no luck: RenderView in My service
My Controller:
use App\Services\Mailer;
class ScriptController extends AbstractController
{
private function getThatNotifSent($timeframe, Mailer $mailer)
{
// Some code
foreach ( $users as $user ) {
$mailer->sendNotification($user, $cryptos, $news, $timeframe);
$count++;
}
$response = new JsonResponse(array('Mails Sent' => $count));
return $response;
}
}
My service:
<?php
// src/Service/Mailer.php
namespace App\Services;
use Symfony\Component\DependencyInjection\ContainerInterface;
class Mailer
{
private $mailer;
private $templating;
public function __construct(\Swift_Mailer $mailer ,ContainerInterface $templating)
{
$this->mailer = $mailer;
$this->templating = $templating;
}
public function sendNotification($user, $cryptos, $news, $timeframe)
{
$message = (new \Swift_Message('Your Daily Digest Is Here!'))
->setFrom('[email protected]')
->setTo($user->getEmail())
->setBody(
$this->templating->render(
'emails/notification.html.twig',
array(
'timeframe' => $timeframe,
'cryptos' => $cryptos,
'user' => $user,
'news' => $news,
)
),
'text/html'
)
->setCharset('utf-8');
$this->mailer->send($message);
return true;
}
}
My service.yaml
# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
locale: 'en'
images_directory: '%kernel.project_dir%/public/images/blog'
services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
public: false # Allows optimizing the container by removing unused services; this also means
# fetching services directly from the container via $container->get() won't work.
# The best practice is to be explicit about your dependencies anyway.
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/*'
exclude: '../src/{Entity,Migrations,Tests,Kernel.php}'
# controllers are imported separately to make sure services can be injected
# as action arguments even if you don't extend any base controller class
App\Controller\:
resource: '../src/Controller'
tags: ['controller.service_arguments']
# add more service definitions when explicit configuration is needed
# please note that last definitions always *replace* previous ones
App\EventListener\LoginListener:
tags:
- { name: 'kernel.event_listener', event: 'security.interactive_login' }
App\Services\Mailer:
arguments: ["@mailer", "@templating”]
UPDATE:
I have updated my code to follow Taylan answer. My Mailer service now looks like the following (no change to sendNotification Made)
<?php
// src/Service/Mailer.php
namespace App\Services;
use Symfony\Bundle\TwigBundle\TwigEngine;
class Mailer
{
private $mailer;
private $templating;
public function __construct(\Swift_Mailer $mailer ,TwigEngine $templating)
{
$this->mailer = $mailer;
$this->templating = $templating;
}
I still had the same error message. But after doing research online, I’ve updated my framework.yaml to the following after reading on this helpful link: https://github.com/whiteoctober/BreadcrumbsBundle/issues/85
framework:
templating: { engines: [twig] }
It worked
Thanks for your help.
ContainerInterface typehint gives you the container, yet you named it $templating
. You're supposed to get templating from container like this $this->templating = $container->get('templating')
.
But do you really need the container in the first place? You should be able to inject templating directly by typehinting like this Symfony\Bundle\TwigBundle\TwigEngine $templating
instead of Symfony\Component\DependencyInjection\ContainerInterface $container
.
P.S: You can search for services via php bin/console debug:container
command.