Reputation: 728
Looking at the code of the Sylius Bundle for Symfony I noticed the Resource Bundle has an interesting way of defining resource controllers as services. Here is the cart item controller service configuration in XML
<service id="sylius.controller.cart_item" class="%sylius.controller.cart_item.class%">
<argument type="service">
<service factory-service="sylius.controller.configuration_factory" factory-method="createConfiguration" class="Sylius\Bundle\ResourceBundle\Controller\Configuration">
<argument>sylius</argument>
<argument>cart_item</argument>
<argument>SyliusCartBundle:CartItem</argument>
</service>
</argument>
<call method="setContainer">
<argument type="service" id="service_container" />
</call>
</service>
If I understand it correctly this code instantiates the controller class and passes as the constructor argument the result of a call to the factory-method "createConfiguration" in the factory-service class. Arguments are specified, so everything is fine.
My question is twofold: 1) Where is this documented? I could not find one example of this kind of arguments-as-a factory-callable in the docs. 2) What would be the YAML version of this?
Thanks...
Upvotes: 4
Views: 1919
Reputation: 442
I was trying to override the CartItemController and came across this, because I thought i needed to do it this way. But it's not the way to go. Anyways, to answer your question. Here is how the xml transforms into yaml
(because the solution suggested by Alexei Tenitski didn't work for me, I did it like so)
sylius.controller.cart_item:
class: Sylius\Bundle\ResourceBundle\Controller\ResourceController
arguments: ["@sylius.cart_item.config_factory"]
calls:
- [setContainer, ["@service_container"]]
sylius.cart_item.config_factory:
class: Sylius\Bundle\ResourceBundle\Controller\Configuration
factory_class: Sylius\Bundle\ResourceBundle\Controller\ConfigurationFactory
factory_method: createConfiguration
arguments: ["sylius", "cart_item", "SyliusCartBundle:CartItem"]
But I'm guessing you were trying to override the CartItem controller, right? :) that's what I was trying to do anyways.
In the Sylius Docs is explained how you would go about doing that. Like this :
location : yourbundle/resources/config/config.yml
sylius_cart:
classes:
item:
controller: YourBundle\Controller\CartItemController
Also, make sure that if you configure the route to your new controller action, you use the controller service instead of the normal approach.
location : yourbundle/resources/config/routing.yml
mybundle_ajaxcart_add:
path: /ajax/cart/add
defaults: { _controller: sylius.controller.cart_item:addAjaxAction }
I wanted to post it here, because I was looking for this for about half a day and probably someone is going to be looking for the same solution. And I like to save that person the headache ;)
Upvotes: 2
Reputation: 9360
Here is the way:
<service id="sylius.controller.cart_item" class="%sylius.controller.cart_item.class%">
<argument type="service">
<service factory-service="sylius.controller.configuration_factory" factory-method="createConfiguration" class="Sylius\Bundle\ResourceBundle\Controller\Configuration">
<argument>sylius</argument>
<argument>cart_item</argument>
<argument>SyliusCartBundle:CartItem</argument>
</service>
</argument>
<call method="setContainer">
<argument type="service" id="service_container" />
</call>
</service>
Can be written as the following in yml
sylius.controller.cart_item:
class: %sylius.controller.cart_item.class%
arguments:
- "@=service('sylius.controller.configuration_factory').createConfiguration('sylius', 'cart_item', 'SyliusCartBundle:CartItem')"
calls:
- [setContainer, ["@service_container"]]
Upvotes: 4
Reputation: 808
You can find the answer to both of your questions in the dependency injection docs.
As far as defining a service nested under another service in YAML, it doesn't seem the parser that ships with Symfony can handle that, but I did find someone's pet project that seems to aim for this functionality: https://gist.github.com/Mikulas/8004470
Upvotes: 2