title: Symfony 2: Resolve circular reference
body: <p>I am working on a Symfony 2 WebApp project. The logic of the integrated shop is implemented in <code>MyShopBundle</code>.</p>
  
  <p>After adding a <code>Twig Extension</code> to the bundle I get an exception:</p>
  
  <p>I totally understand the meaning of this message but so far I found no solution to solve the problem:</p>
  
  <p>The <code>PaymentServices</code> within the <code>MyShopBundle</code> offers all kind of different services related to the payment process. Beside others, it observes the payment status and automatically send e-mail notifications to the users. Additional it offer the <code>isPaymentComplete(int userId)</code>.</p>
  
  <p>To render the content of an e-mail from a <code>Twig</code> template the <code>PaymentServices</code> needs a reference to <code>Twig_Environment</code>. The services gets this reference from its constructor:  </p>
  
  <pre><code>class MyPaymentService {
      protected $twig;
  
      public function __construct(\Twig_Environment $twig, ...) {
          $this-&gt;twig = $twig;
          ...
      }
  
      public function updatePaymentStatus(int userId) {
          // Update Payment
          ...
  
          // Send notification to user
          $mailBody = $this-&gt;twig-&gt;render('MyShopBundle:Emails:statusUpdate.html.twig', array('user_name' =&gt; $username));
          ...
      }
  
      public function isPaymentComplete(int userId) {
          ...
          return true;   
      }
  }
  </code></pre>
  
  <p>The <strong>Twig Extension</strong> on the other hand need a reference to the <code>PaymentService</code> to create a twig version of <code>isPaymentComplete(int userId)</code>:</p>
  
  <pre><code>class ShopExtension extends \Twig_Extension {
      private $paymentService;
  
      public function __construct(PaymentService $service, ...) {
          $this-&gt;paymentService = $service;
          ...
      }
  
      public function getName() {
          return 'my_shop_bundle_extension';
      }
  
      public function getFunctions() {
          $functions = array();
  
          $functions[] = new \Twig_SimpleFunction('msb_IsPaymentComplete', array(
              $this,
              'msb_IsPaymentComplete'
          ));
  
          return $functions;
      }
  
      public function msb_IsPaymentComplete($user) {
          if ($this-&gt;paymentService)
              return $this-&gt;paymentService-&gt;isPaymentComplete($user);
          else 
              return false;
      }
  } 
  </code></pre>
  
  <p>This is the service definition in <code>service.yml</code></p>
  
  <pre><code>services:
      shop.payment.service:
          class: MyShopBundle\Service\PaymentService
          arguments: 
            - "@twig"
            - ...
  
      app_subscription.twig_extension:
          class: MyShopBundle\Twig\ShopExtension
          arguments: 
              - "@shop.payment.service"
          tags:
            - { name: twig.extension }
  </code></pre>
  
  <p>The source of the exception is clear:</p>
  
  <p><strong>PaymentService --> Twig --> ShopExtension --> PaymentService</strong></p>
  
  <p><strong>Question is:</strong> How to solve this?</p>
  
  <p>I found other questions, dealing with circular references in Symfony. But they were all related to some special cases using some common Bundles/Services like <code>Doctrine</code>, <code>FOSUserBundle</code>, etc. The solutions discussed in these threads do not work here.</p>
  
  <p>The obvious solution would be to split up the <code>PaymentService</code> into two parts: One that includes <code>isPaymentComplete(int userId)</code> and one that offers <code>updatePaymentStatus</code>. But this not as easy as its sound, since these two methods use other common <code>PaymentService</code> methods. To avoid to just move the circular reference on lever deeper I would need to split <code>PaymentService</code> into three parts:</p>
  
  <ul>
  <li>Service1 including <code>isPaymentComplete</code></li>
  <li>Service2 including <code>updatePaymentStatus</code></li>
  <li>Service3 including all common methods used by Service1 and 2</li>
  </ul>
  
  <p>That would work (most likely) but would be very, very ugly. All methods in these three Services serve the same purpose (handle Payments) and should thus be included in the same Services. Breaking up the Services into different parts would have nothing to do with code structuring but would only by a hack to break up the circular reference.</p>
  
  <p>I already tried to move the reference from the constructors to a setter:</p>
  
  <pre><code>services:
      shop.payment.service:
          class: MyShopBundle\Service\PaymentService
          calls:
            - [ setTwig, [ "@twig" ] ]
  
      app_subscription.twig_extension:
          class: MyShopBundle\Twig\ShopExtension
          calls:
            - [ setService, [ "@shop.payment.service" ] ]
          tags:
            - { name: twig.extension }
  </code></pre>
  
  <p>The result is still the same. </p>
  
  <p>So: Is there any <em>clean</em> solution to solve this referencing issue?</p>