2013-03-25 13 views
8

symfony 2(xml configs)で引数にサービスIDを動的に設定することは可能ですか(たとえば、パラメータで設定できるクラス名のようなもの)ですか?symfony2の引数に動的なサービスIDがありますか?

アイデアを設定することである

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

動作しない以下のparam%dynamic_service_name%動的に「サービス1」または「サービス2」、とても必要なインスタンス/オブジェクトはMYSERVICEクラスに渡され、例えばしますExtension :: load()で$ container-> setParameter( 'dynamic_service_name'、 'service1');を実行します。ストレートSymfony2のドキュメントから

どうもありがとう

+0

あなたが提供したコードにパラメータを追加してください。あなたのコードにはパラメータはありません。 – Seer

答えて

1

;)

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

はあなたが後にしている何本か?

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

編集:

これは、パラメータを使用して、私のサービスの一つです。しかし、それはYAMLにあります。これはうまく動作します。ご覧のとおり、クラスの名前空間をパラメータ内のクラスに使用しています。

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

とあなたのバンドルのクラスに追加:

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

残念ながら、この "解決策"では、単にサービスに文字列を渡し、オブジェクト/サービスのインスタンスは渡さないためです。 – user1826848

+0

PHPのファイル名で試してみたら、うまくいきません...ネームスペースでクラス名を使用していることを確認してください。そのドキュメントのページをもう一度見てください。私はあなたのサービスの1つで、YAMLにありますが... – Seer

+0

もちろんパラメータを使ってクラス名を動的に設定することはできますが、サービスのIDを動的に設定したいのです – user1826848

16

あなたはCompilerPassを使用することができます

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

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

FOLLOW UP

のSymfony 2.4以降あなたはExpression Languageを使用することができますこのように:

<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

あなたは解決策が美しいです!ありがとうございました! :) –

0

これは、コンテナ自体を工場として使用する方法とほぼ同じです。次に、 'dynamic_service_name'をservice1またはservice2のいずれかとして定義すると、そのサービスにロードされます。

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

は、2つの小さな違いがあります、ここではYAMLで同等だ

<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

ピーター・フォックス」答えに追加する(工場出荷時のためのXMLは2.6でわずかに異なっているが、それでも同じように動作するはずです) 2つのサービスのクラスがどのように指定されているか。クラスとしてのファイル名の使用に慣れていないし、foobar\service1もPSRに準拠していないので、これらを置き換えた。

1

parameter()機能を使用してサービス定義にパラメータを読み込み、service()機能を持つサービスを作成することができます。つまり、あなたのparameters.ymlでは、あなたのサービスで

parameters: 
     dynamic_service_name: mydynamicservice 

を動的サービス

を作成することができます。yml

myservice: 
     class: My\Service 
     arguments:['@=service(parameter("dynamic_service_name"))'] 
関連する問題