title: Bind interface to concrete class with Symfony's service container
body: <p>With C#, ASP.NET MVC and something like <a href="http://autofac.org/" rel="nofollow">Autofac</a>, I can create an interface <code>IProductService</code> and bind it to a concrete implementation class <code>ProductService</code> with code like this (where builder is an <code>Autofac.ContainerBuilder</code>):</p>
  
  <pre><code>builder.RegisterType&lt;ProductService&gt;().As&lt;IProductService&gt;();
  </code></pre>
  
  <p>Then in my controller, I can create a constructor which looks like the below:</p>
  
  <pre><code>using System.Web.Mvc;
  
  namespace SomeNamespace
  {
      public class HomeController : Controller
      {
          private IProductService _productService;
  
          public HomeController(IProductService productService)
          {
              this._productService = productService;
          }
      }
  }
  </code></pre>
  
  <p>Using reflection, Autofac is able to figure out I'd like an <code>IProductService</code> implementation injected into my constructor and provide the type I registered earlier as the concrete implementation type, resolving dependencies in the <code>ProductService</code> class as necessary in order to create an instance for the controller to use.</p>
  
  <hr>
  
  <p>I'd like to achieve something similar using Symfony. My current understanding is that I can make use of Symfony's service in the following manner:</p>
  
  <pre><code>services:
      product_repository:
          class: App\WebBundle\Repository\ProductRepository
      product_service:
          class: App\WebBundle\Service\ProductService
          arguments: ["@product_repository"]
      home_controller:
          class: App\WebBundle\Controller\HomeController
          arguments: ["@product_service"]
  </code></pre>
  
  <p>And then use a controller like this:</p>
  
  <pre><code>namespace App\WebBundle\Controller;
  
  use Symfony\Bundle\FrameworkBundle\Controller\Controller;
  
  public class HomeController extends Controller {
  
      private $productService;
  
      public function __construct(IProductService $productService) {
          $this-&gt;productService = $productService;
      }
  }
  </code></pre>
  
  <p>This works, but it's far from ideal because I now not only provide the interface type-hints in the constructor (which already make it clear which service I want injected), I also have to figure out the service names and provide them in the configuration file for every class I want that uses services.</p>
  
  <p>The other alternative I can see is making use of of the <code>get</code> function on <code>Symfony\Bundle\FrameworkBundle\Controller\Controller</code>, like so:</p>
  
  <pre><code>namespace App\WebBundle\Controller;
  
  use Symfony\Bundle\FrameworkBundle\Controller\Controller;
  
  public class HomeController extends Controller {
  
      private $productService;
  
      public function __construct() {
          $this-&gt;productService = $this-&gt;get("product_service");
      }
  }
  </code></pre>
  
  <p>This approach works, except I'm now completely reliant on Symfony's service container (making moving to another framework in the future difficult), my IDE has no idea what type <code>$this-&gt;productService</code> is and so I've also lost autocompletion. It's also not obvious to other developers where the service comes from, and I have to repeatedly refer back to the config file to find out which class is registered with the id of "product_service" (I can't use my IDE's navigation tools to jump to the declaration of the interface or find all classes which implement the interface).</p>
  
  <p>My understanding is that Laravel's Illuminate Container component provides the functionality I'd like to achieve (using reflection to figure out which type is being hinted in a constructor/method and resolving dependencies using bindings provided by the developer) but I'm unsure if it would be possible to set up easily with Symfony. Is there any way I can achieve this functionality whilst still using Symfony (perhaps I can listen to the <code>kernel.controller</code> and do stuff there)? </p>