2014-12-13 5 views
19

Ich bin neu von symfony Welt. Ich möchte in meinem Dienst nutzen machen, aber ich habe diesen FehlerRenderView in Mein Service

Call to undefined Methode Render

Ich weiß, dass Render Verknüpfung von

/** 
* Returns a rendered view. 
* 
* @param string $view  The view name 
* @param array $parameters An array of parameters to pass to the view 
* 
* @return string The rendered view 
*/ 
public function renderView($view, array $parameters = array()) 
{ 
    return $this->container->get('templating')->render($view, $parameters); 
} 

Aber ich don‘ Ich weiß, was ich zu Injection in meinem Service habe. Ich weiß sogar mit php app/console container:debug Befehl, den ich sehe alle meine Dienste zur Verfügung, aber ich weiß nicht, wie nehmen/wählen Sie die richtige

Update

Ich versuchte

arguments: [@mailer,@templating] 

hinzufügen aber ich habe ServiceCircularReferenceException

UPDATE

änderte ich meine service.yml mit

arguments: [@service_container] 

und sogar meinen Dienst

$email = $this->service_container->get('mailer'); 
$twig = $this->service_container->get('templating'); 

für Service-Mail (swift) und rendern.

Ich glaube nicht, dass es die beste Lösung ist. Ich würde gerne Injektion nur mailer und templating

UPDATE Nach Jasons Antwort Ich bin mit Symfony 2.3

mein services.yml

services: 
    EmailService: 
     class: %EmailService.class% 
     arguments: [@mailer,@templating,%EmailService.adminEmail%] 

Ich habe diese ServiceCircularReferenceException

Antwort

23

Sie sind richtig über renderView(), es ist nur eine Abkürzung für Controller. Wenn Sie eine Serviceklasse verwenden und den Vorlagenservice injizieren, müssen Sie lediglich Ihre Funktion in render() ändern. Also statt

return $this->renderView('Hello/index.html.twig', array('name' => $name)); 

würden Sie

return $this->render('Hello/index.html.twig', array('name' => $name)); 

Updates von Olivias Antwort verwenden:

Wenn Sie zirkuläre Referenz Fehlermeldungen erhalten, der einzige Weg, um sie herum ist, den gesamten Behälter zu injizieren . Es gilt nicht als Best Practice, ist aber manchmal nicht zu vermeiden. Wenn ich darauf zurückgreifen muss, setze ich meine Klassenvariablen immer noch im Konstruktor, damit ich so tun kann, als ob sie direkt injiziert würden.Also werde ich tun:

use Symfony\Component\DependencyInjection\ContainerInterface; 

class MyClass() 
{ 
    private $mailer; 
    private $templating; 

    public function __construct(ContainerInterface $container) 
    { 
     $this->mailer = $container->get('mailer'); 
     $this->templating = $container->get('templating'); 
    } 
    // rest of class will use these services as if injected directly 
} 

Randbemerkung, ich meine eigenen Standalone-Service nur in Symfony 2.5 getestet und hat keinen zirkulären Verweis erhalten, indem die Mailer und Templating Dienstleistungen direkt injiziert werden.

+1

das ist klar, aber wenn ich 'inje '[@ mailer, @ templating]' ich muss alle Container injizieren. – monkeyUser

+0

Welche Art von Service erstellen Sie? Ist es ein Standalone oder ist es ein Zuhörer für ein anderes Event? Sie sollten keinen kreisförmigen Referenzfehler mit nur Mailer und Templating erhalten, es sei denn, Sie hören auf ein Ereignis, das diese bereits injiziert. Ich schätze, Sie verwenden das Template zum Rendern einer Vorlage, die für Ihre E-Mails verwendet wird. –

+0

Es ist ein einfacher Dienst, der E-Mail erstellt und rendert emailTemplate – monkeyUser

1

Mit Konstruktor Dependency Injection (getestet mit Symfony 3.4):

class MyService 
{ 
    private $mailer; 
    private $templating; 

    public function __construct(\Swift_Mailer $mailer, \Twig_Environment $templating) 
    { 
     $this->mailer  = $mailer; 
     $this->templating = $templating; 
    } 

    public function sendEmail() 
    { 
     $message = $this->templating->render('emails/registration.html.twig'); 

     // ... 
    } 
} 

Keine Notwendigkeit, Argumente zu konfigurieren.