2013-03-25 4 views
8

Ist es möglich, die Service-ID in einem Argument dynamisch (z. B. wie ein Klassenname, der über Parameter eingestellt werden konnte) in Symfony 2 (xml configs) zu setzen?Dynamische Dienst-ID in einem Argument in symfony2?

folgender Grund nicht

<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" /> 

die Idee zu setzen funktioniert die param% dynamic_service_name% dynamisch "service1" oder "service2", so dass das benötigte instance/Objekt wird myservice-Klasse übergeben, z.B. in der Erweiterung :: load() über $ container-> setParameter ('dynamic_service_name', 'service1');

Vielen Dank

+0

Könnten Sie bitte die Parameter zu dem von Ihnen bereitgestellten Code hinzufügen. In Ihrem Code sind keine Parameter angegeben. – Seer

Antwort

1

Gerade von der Symfony2 docs;)

<!-- 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> 

Ist das, was nach der du bist?

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

Edit:

Dies ist einer meiner Dienste, ein Parameter verwendet wird. Es ist jedoch in YAML. Das funktioniert gut. Wie Sie sehen können, wird der Klassenname mit dem Namespace der Klasse im Parameter verwendet.

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

leider nicht, weil ich mit dieser "Lösung" nur eine Zeichenfolge an den Dienst übergebe und keine Instanz eines Objekts/Dienstes. – user1826848

+0

Wenn Sie es mit den PHP-Dateinamen versuchen, wird das nicht funktionieren ... Stellen Sie sicher, dass Sie den Klassennamen mit dem Namespace verwenden. Sehen Sie sich diese Dokumentationsseite noch einmal an. Ich gebe Ihnen ein Beispiel von einem meiner Dienste, es ist in YAML obwohl ... – Seer

+0

Natürlich ist die dynamische Einstellung eines Klassennamens über einen Parameter möglich, aber ich möchte die ID eines Dienstes dynamisch setzen – user1826848

16

können Sie CompilerPass verwenden:

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

und fügen Sie es Ihrer Bundle Klasse:

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

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

FOLGEN UP:

Seit Symfony 2.4 Sie Expression Language verwenden können so:

<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

Ihre Lösung ist schön! Vielen Dank! :) –

0

Dies ist in etwa, wie es mit dem Container selbst als Fabrik getan werden kann. Sie können dann Ihren 'dynamic_service_name' entweder als service1 oder service2 definieren und er wird in diesem Service geladen. (XML für eine Fabrik ist etwas anders in 2.6, sollte aber immer noch die gleiche Arbeit)

<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

Hinzufügen zu Peter Fox‘Antwort, hier ist das Äquivalent in YAML:

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

Es gibt zwei kleine Unterschiede in wie die Klassen der beiden Dienste angegeben werden. Ich bin nicht vertraut mit der Verwendung von Dateinamen als Klassen und foobar\service1 ist auch nicht PSR-konform, also habe ich diese ersetzt.

1

Sie können einen Parameter in Ihre Service-Definition mit der Funktion parameter() einlesen und einen Service mit der Funktion service() erstellen. So können Sie einen dynamischen Service

In Ihrem parameters.yml

parameters: 
     dynamic_service_name: mydynamicservice 

In Ihren Diensten erstellen.yml

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