Injecting Services in Symfony 2

Hi all,

Let’s have a quick but precise look at injecting various services in Symfony 2 today. Before going any deep, what does it mean by injecting services ? Well, if I am not so wrong, not many PHP frameworks do favour injecting services as Symfony 2 does. Injecting various services into the application is a really beautiful, cool thing, I would say. If you manage to inject services properly, you really don’t want to take care of object creations. Well, what’s injecting service actually is ? Injecting a service in Symfony 2 is, you define, a service or set of services (in PHP, classes) at the application load time, then you reuse those services as much as you want, any time during the execution, without redeclaring or creating objects of those services (classes). In other words it will help you to “standardize and centralize the way objects are constructed in your application” . There are 3 types of injections in Symfony 2, which are,

  1. Constructor Injection
  2. Setter Injection
  3. Property Injection

In this post, I will be discussing about the ‘Constructor Injection’, because I thought it might be useful to know how this type of injection works before knowing the remaining two. 

Good, now let’s inject ‘Container‘ service (you need the most) to our custom built class called ‘TestHelper’. Before doing anything, you need to create class anywhere inside the Bundle. For now, I will be creating a folder called ‘Helper’ under ‘src/Test/HelloBundle’ package. (I have showed in detail, how to create a bundle in my previous post) .

  1. Create a php file called ‘TestHelper.php’ under ‘Test/HelloBundle/Helper’ location.1
  2. Then add the correct namespace and class name (same as the file name). It’s always good to follow standards and it’ll help the journey in Symfony 2 a much easier one. Your ‘TestHelper’ class looks like this,2
  3. Now you need to add the constructor which accepts one parameter, which is the services container. Then what I normally do is, assign that parameter to a class variable, so we can reuse the services container where ever we want. Remember, by default, services container is not widely available in any other location, than ‘Controller’ it self. But lot’s of magic in Symfony 2, happens inside the container. Now, we are in our own location called ‘Helper’ which does not have access to container. But thankful to the injection, we are gaining access to container, inside ‘TestHelper’ class in couple of minutes. So, after inserting the constructor and class variable, our modified ‘TestHelper’ class looks like this,3
  4. So now, we have successfully created our class called ‘TestHelper’, and added the constructor to expect one parameter, which is the Container. Now, here’s the beauty. We don’t create objects such as ‘$testHelper = new TestHelper(new Container());’ anywhere in Symfony 2, by our own. Instead that, we tell Symfony 2 to do that bit for us. There’s a dedicated place in Symfony 2 to tell, inject Container into our newly created ‘TestHelper’ class. That’s the ‘config.yml’ file inside ‘app/config’ directory. Open the ‘config.yml’ file and add this piece of code at the end of the file. (Please make sure you have the correct indentations in the yaml file).
     
      services:
           test_helper_service:
              class: Test\HelloBundle\Helper\TestHelper
              arguments: ["@service_container"] 
    
  5. So our, modified ‘config.yml’ file looks like this,4
  6. Now, you have successfully instructed the application to inject ‘Container’ to our newly created ‘TestHelper’. To access this service and call it’s function will be really simple from now on. Take a look at how we call this service below,
      
     
            $this->container->get('test_helper_service'); 
      
  7. To call a function which is inside this class will be as simple as this,
      
      
     
            $this->container->get('test_helper_service')->testFunction();
      

    (Replace ‘testFunction’ with the name of your actual function).

 

In this post, we have discussed how injecting services work in Symfony 2 environment. We injected ‘Container’ to a newly created class, we declared services parameters in config.yml and accessed using the get() method. Remember, the get method is accessible via Controller or any class which extends the ContainerAware.

I hope you enjoyed this post. Feel free to bombard the comments section below with your feedback, questions, suggestions and almost everything.

Thanks 🙂

Share

10 thoughts on “Injecting Services in Symfony 2

  1. I really like the simplicity of this article and how you mixed a bit of theory with a practical example.
    Anyway I’m sure you are aware that injecting the container is a bad practice: it violates the minimum knowledge principle, and indirectly exposes all your services to the one you are referencing. Ultimately it will lead to confusing and coupled code.
    Container injection is only acceptable when you are dealing with factory services.
    It would be better If you showed how to inject one service into another, for example a cache storage and a cache writer.

    • Anjana Silva says:

      Thanks Luciano. Yes I am aware of the downside of injection. I will include these factors in one of my future post. Many thanks. Anjana

  2. przemo_li says:

    When I do not want to inject whole container but single service… How do I know what value should I provide to arguments: ?

    • Anjana Silva says:

      Hello @prezemo_li ,

      Type this command in your console to see available service arguments.
      “php app\console debug:container” (without quotes) . This will list you all the available arguments within your project.

      Many thanks,

Leave a Reply to przemo_li Cancel reply

Your email address will not be published. Required fields are marked *