Wednesday, February 9, 2011

Dependency injection for Controllers

To get dependency injection working properbly for controllers in your Symfony2 bundles you have to take care of several things, let's start with an example service configuration:

Service config
# src/MyBundle/Resources/config/config.yml 
services: 
  view: 
    class: "MyBundle\View"
    shared: true
    arguments: 
      container: "@service_container"
        
  my_bundle_controller_index: 
    class:  "MyBundle\Controller\IndexController"
    shared: true
    arguments: 
      view: "@view"
    calls:
      - [ setContainer, ["@service_container"] ]

The name of the controller service is my_controller_bundle_index.
By default your routing.(yml|xml|php) file would look like this:
# src/MyBundle/Resources/config/routing.yml 
my_bundle_route:  
  pattern: my/bundle/route  
  defaults: 
    _controller: MyBundle:IndexController:indexAction

Your service configuration is properly loaded via your dependency injection extension (src/MyBundle/DependencyExtension/MyExtension.php) but nothing happens, why? In your routing file you have to specifiy the controller with his service name (my_bundle_controller_index) and not his bundle namepath. Change your routing file to:
# src/MyBundle/Resources/config/routing.yml 
my_bundle_route:  
  pattern: my/bundle/route  
  defaults: 
    _controller: my_bundle_controller_index:indexAction // not: MyBundle:IndexController

Now everything should work, besides there are some more things you should know:
  • Your controller should implement the interface ContainerAware or the base symfony2 controller class symfony\Bundle\FrameworkBundle\Controller\Controller
  • Your dependency injection extension should load all required configuration files (especially the one with the service vonfiguration)
  • Your bundle routes are registered in the app/config/routing.(yml|xml|php):
    # app/config/routing.yml 
    my_bundle:
        resource: "@MyBundle/Resources/config/routing.yml"
  • You loaded your bundle config in your app/config(_%environment%).(yml|xml|php):
  • # app/config.yml 
    my_bundle.config: ~
    

1 comment:

  1. Hey, thanks for your thoughts and manual.

    Since Symfony 2.8 there is autowiring feature. So it was a small step to create bundle, that adds autowiring to controllers by default: http://www.tomasvotruba.cz/blog/2016/03/10/autowired-controllers-as-services-for-lazy-people/

    What do you think?

    ReplyDelete