2015-12-10 30 views
6

Mam FooService, który pobiera niektóre dane z innej usługi konfiguracji.Jak wprowadzić wynik metody usługi jako argument dla innej usługi?

Mam tę usługę konfiguracji, ponieważ konfiguracja różni się w zależności od danych żądania. Usługa konfiguracji ma wtyczkę RequestStack i tworzy odpowiednią tablicę konfiguracji.

My FooService wygląda następująco:

class Foo 
{ 
    private $config; 

    /** 
    * @param Config $config 
    */ 
    public function __construct(Config $config) { 
     $this->config = $config->getData(); 
    } 
} 

Jednak zamiast wstrzykiwania usługę, wolę wstrzykiwać tylko wynik metoda połączenia z getData, jak to jest prostsze dla testów jednostkowych. Nie będę musiał kpić z konfiguracji, mogę po prostu przekazać tablicę.

mojego obecnego service.yml ma definicji takich jak:

config: 
    ... 

foo: 
    class: Kopernikus\LeBundle\Service\Foo 
    arguments: 
     - @config 

Próbuję zmienić moje foo definicję jak dla metod fabrycznych poprzez:

foo: 
    class: Kopernikus\LeBundle\Service\Foo 
    arguments: 
     - [@config, getData] 

to jeszcze zbyt wstrzykuje całą usługę.

Jak wprowadzić wynik metody usługi jako argument dla innej usługi?

Odpowiedz

8

Można to osiągnąć z językiem ekspresji (New in Symfony 2.4)

jak opisano w dokumencie here można zrobić coś jako przykład:

config: 
    ... 

foo: 
    class: Kopernikus\LeBundle\Service\Foo 
     arguments: ["@=service('config').getData()"] 

nadzieję, że ten help

+1

Nawiasy są zbyt duże, ponieważ wprowadzają tablicę tablicy. Po prostu '" @ = service ('config'). GetData() "" wystarcza. =) – k0pernikus

+0

Został przeniesiony [tutaj] (http://symfony.com/doc/3.3/service_container/expression_language.html) od wersji ** 3 ** – Trix

0

Zasadniczo prosisz o pojemnik do wstrzykiwania zależności. Możesz stworzyć własną, która ma prostą funkcję (np.) get(), która zwraca nowe wystąpienie Foo? Można go zdefiniować w celu utworzenia nowych obiektów po każdym wywołaniu get() lub więcej singletonu, który zawsze zwraca ten sam obiekt (przez przechowywanie go w prywatnej zmiennej statycznej).

np

<?php 
class FooContainer implements YourContainerInterface { 
    public static function get() { 
     // Config logic here 
     return new Foo($config); 
    } 
} 
+0

Wygląda na to, że OP pyta, jak wprowadzić iniekcję lt wywołania metody do usługi zamiast samej usługi - chociaż nie rozumiem jasno, dlaczego chcieliby to zrobić, więc mogę nie rozumieć problemu. –

+0

@JeremyHarris Zaktualizowałem przypadek użycia, dlaczego chcę to zrobić. – k0pernikus

+0

Jedynym sposobem na przekazanie funkcji w taki sposób jest łańcuch, który nie jest idealny, ponieważ nie można wykonywać na nim żadnych testów (bez użycia dodatkowej logiki). Odpowiednim sposobem zrobienia tego w PHP jest obiekt kontenera. – Ian

Powiązane problemy