2013-03-25 14 views
8

Czy można ustawić identyfikator usługi w argumencie dynamicznie (np. Jak nazwa klasy, która może być ustawiona za pomocą parametru) w Symfony 2 (xml configs)?Dynamiczny identyfikator usługi w argumencie w symfony2?

Następujące nie działa

<service id="myservice" class="myservice.php"> 
    <argument type="service" id="%dynamic_service_name%" /> 
</service> 

<service id="service1" class="foobar\service1" /> 
<service id="service2" class="foobar\service1" /> 

chodzi o to, aby ustawić param% dynamic_service_name% dynamicznie „służby1” lub „Usługa2”, więc potrzeba przykład/przedmiot wprowadza się do MojaUsluga klasy, np w rozszerzeniu :: load() przez $ container-> setParameter ('dynamic_service_name', 'service1');

Thanks a lot

+0

Czy możesz dodać parametry do podanego kodu. W twoim kodzie nie ma parametrów. – Seer

Odpowiedz

1

Prosto z docs Symfony2;)

<!-- app/config/config.xml --> 
<parameters> 
    <parameter key="my_mailer.class">Acme\HelloBundle\Mailer</parameter> 
    <parameter key="my_mailer.transport">sendmail</parameter> 
</parameters> 

<services> 
    <service id="my_mailer" class="%my_mailer.class%"> 
     <argument>%my_mailer.transport%</argument> 
    </service> 
</services> 

Czy to Ty jesteś po?

http://symfony.com/doc/current/book/service_container.html#service-parameters

Edit:

Jest to jeden z moich usług, za pomocą parametru. Jednak jest w YAML. Działa to dobrze. Jak widać, używa on nazwy klasy z przestrzenią nazw klasy w parametrze.

parameters: 
    seer_ukd_wright_gallery.gallery_helper.class: SeerUK\DWright\GalleryBundle\DependencyInjection\GalleryHelper 

services: 
    seer_ukd_wright_gallery.gallery_helper: 
     class: %seer_ukd_wright_gallery.gallery_helper.class% 
     arguments: 
      em: "@doctrine.orm.entity_manager" 
+0

Niestety nie, ponieważ z tym "rozwiązaniem" po prostu przekazuję ciąg do usługi, a nie do instancji obiektu/usługi .. – user1826848

+0

Jeśli próbujesz go z nazwami plików php, to nie zadziała ... Upewnij się, że używasz nazwy klasy wraz z przestrzenią nazw. Spójrz jeszcze raz na tę stronę dokumentacji. Dam ci przykład z jednej z moich usług, ale w YAML ... – Seer

+0

oczywiście ustawienie nazwy klasy dynamicznie za pomocą parametru jest możliwe, ale chcę ustawić identyfikator usługi dynamicznie – user1826848

16

Można użyć CompilerPass:

class DynamicServiceCompilerPass implements CompilerPassInterface 
{ 
    public function process(ContainerBuilder $container) 
    { 
     $container->getDefinition('myservice') 
      ->setArguments(array(new Reference($container->getParameter('dynamic_service_name')))); 
    } 
} 

i dodać go do swojej klasy zestawie:

public function build(ContainerBuilder $container) 
{ 
    parent::build($container); 

    $container->addCompilerPass(new DynamicServiceCompilerPass()); 
} 

Kontynuacja:

Od Symfony 2.4 można użyć Expression Language w ten sposób:

<services> 
    <service id="myservice" class="My\Service"> 
     <argument type="expression">service(container.hasParameter('dynamic_service_name') ? parameter('dynamic_service_name') : 'default_service_name')</argument> 
    </service> 
</services> 
+0

Twoje rozwiązanie jest piękne! Dziękuję Ci! :) –

0

Z grubsza można to zrobić, używając samego pojemnika jako fabryki. Następnie możesz zdefiniować swoją "dynamic_service_name" jako service1 lub service2, która zostanie załadowana do tej usługi. (XML dla fabryki jest nieco inny w 2.6, ale powinien nadal działają tak samo)

<service id="service1" class="foobar\service1" /> 
<service id="service2" class="foobar\service1" /> 

<service id="some.service" class="foobar\service1" 
      factory-service="service_container" 
      factory-method="get"> 
     <argument>%dynamic_service_name%</argument> 
    </service> 

<service id="myservice" class="myservice.php"> 
    <argument type="service" id="some.service" /> 
</service> 
0

Dodawanie do Peter Fox”odpowiedź, oto równowartość w YAML:

some.service: 
    class: Foobar\Service1 
    factory_service: service_container 
    factory_method: get 
    arguments: 
     - %dynamic_service_name% 
myservice: 
    class: MyService 
    arguments: 
     - @some.service 

Istnieją dwa małe różnice w sposób określania klas obu usług. Nie jestem zaznajomiony z używaniem nazw plików jako klas i foobar\service1 nie jest również zgodny z PSR, więc wymieniłem je.

1

Możesz odczytać parametr w definicji usługi za pomocą funkcji parameter() i utworzyć usługę za pomocą funkcji service(). Więc można utworzyć dynamiczną usługę

W swojej parameters.yml

parameters: 
     dynamic_service_name: mydynamicservice 

w twoich usług.yml

myservice: 
     class: My\Service 
     arguments:['@=service(parameter("dynamic_service_name"))']