Symfony 2: dependency injection und Merkmale
Ich versuche einen Weg zu finden, verwenden Sie das Symfony 2 Dependency Injection-Komponente mit der neuen PHP 5.4 Merkmale.
Um eine lange Geschichte kurz (nicht so kurz ist, eigentlich), mein Projekt hat entkoppelt View-Klassen, die alle Ihre eigenen, speziellen Konstruktor. Jede Ansicht kann null oder mehr Helferlein, sind definiert als Merkmale:
trait TranslatorHelper
{
/**
* @var Translator
*/
protected $translator;
/**
* @param Translator $translator
*/
protected function setTranslator(Translator $translator)
{
$this->translator = $translator;
}
/**
* @param string $text
* @return string
*/
public function translate($text)
{
return $this->translator->translate($text);
}
}
-
class UserEditView extends AbstractView
{
use TranslatorHelper;
public function __construct(User $user, UserEditForm $form)
{
//...
}
}
Ich würde gerne eine Methode in meinem controller renderView()
, führt, dass die setter-injection, basierend auf alle Merkmale verwendet, die von der View-Klasse, vor dem Rendern der Ansicht:
class Controller
{
public function renderView(View $view)
{
//Check what traits are used by $view, and inject their dependencies
//{...}
//Then render the View
return $view->render();
}
}
Jede Idee, wie dies zu tun mit der DependencyInjection
Komponente?
Das Hauptproblem ist offensichtlich, dass die Ansichten nicht erstellt werden, indem die DI-container, sondern kann überall erstellt werden, in die Anwendung fließen. Es ist nur, bevor Sie gerendert werden, dass die Abhängigkeiten injiziert werden müssen.
Einen letzten Hinweis: ich bin nicht gebunden an das Symfony Komponente. Alle führen auf eine andere DI-container würde geschätzt werden, wie gut.
- Sie können versuchen, DI mit AOP: github.com/schmittjoh/JMSAopBundle/blob/master/Resources/doc/..., um automatisch injizieren services von annotataion von Eigenschaften und Argumente.
- Das problem ist, dass ich wollte, dass die Helferlein (wie
TranslatorHelper
) generische, also ideal, sollten Sie nicht enthalten die Projekt-spezifische id der Abhängigkeiten in den container.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich denke, die Züge sind nicht gedacht, um verwendet werden, um DI auf diese Weise. Was ich tun würde, in einem ähnlichen Szenario wird constructor injection (oder auch setter wäre in Ordnung, obwohl Konstruktor ist besser, wenn möglich) in die view-Klasse, die Merkmale zu injizieren, der direkt die benötigten Dienste.
Wenn Sie denken, dass die Züge von einer Klasse implementiert werden statisch definiert werden, bevor die Anwendung ausgeführt wird, so Sie nicht wirklich brauchen, zu prüfen, die Züge führen Sie eine dynamische Injektion. Sie wissen, was Dienstleistungen, die Sie benötigen, bevor Sie ausgeführt wird, nur denke Merkmal, als wären Sie Schnittstellen mit konkreten Methode.
TranslatorHelper
Charakterzug würde verwenden Sie den Übersetzer, wies auf die von dertranslator
container-Schlüssel.Symfony 3.3 eingeführt, die Idee von autowired-Dienste.
Alles, was Sie tun müssen ist, erstellen Sie eine Set-Funktion in Ihrer Eigenschaft und fügen Sie den
@required
annotation.Referenz: https://symfony.com/doc/current/service_container/autowiring.html#autowiring-other-methods-e-g-setters