title: Overriding dependency at runtime in AngularJS
body: <p>I have a service called <code>$doggedHttp</code>, which exposes the same interface as <code>$http</code>.
  Now I want to create a <code>$doggedResource</code> service which is the angular <code>$resource</code> service on top of <code>$doggedHttp</code> instead of <code>$http</code>. In other word I want to inject <code>$doggedHttp</code> as the <code>$http</code> service.</p>
  
  <p>Also, in my application I want to be able to create both <code>$doggedResource</code> and <code>$resource</code>. Thus I cannot simply override <code>$http</code> with <code>$doggedHttp</code>.</p>
  
  <p>I thought dependency injection should make this scenario easy to solve. Am I wrong ?</p>
  
  <p>Instead I had to go deep into the angular source code to finally came up with a quite ugly  solution : </p>
  
  <pre><code>angular.module('doggedResource', ['ngResource', 'doggedHttp'])
    .config(function() {
      var ngResource = angular.module('ngResource'),
          doggedResource = angular.module('doggedResource');
  
      // replace the placeholder below with the $resource factory from ngResource
      doggedResource._invokeQueue[1][2][1][2] = ngResource._invokeQueue[0][2][1][2];
  })
  .factory('$doggedResource', ['$doggedHttp', '$parse', null /* this is just a placeholder */]);
  </code></pre>
  
  <p>Is there a better solution ?</p>
  
  <hr>
  
  <p>Remark that we cannot use <code>$provide.decorator</code> to replace the injected <code>$http</code> service.
  To illustrate the problem, here are the relevant parts of <a href="http://code.angularjs.org/1.0.8/angular-resource.js" rel="nofollow">angular-resource.js</a> :</p>
  
  <pre><code>angular.module('ngResource', ['ng']).
    factory('$resource', ['$http', '$parse', function($http, $parse) {
  
      function ResourceFactory(url, paramDefaults, actions) {
      }
  
      return ResourceFactory;
    }
  </code></pre>
  
  <p>Looking at the code above, the <code>$provide.decorator</code> callback will be passed ResourceFactory as an argument. At that time the dependency <code>$http</code> has already been resolved. And since ResourceFactory use <code>$http</code> inside a closure we cannot change it.</p>
  
  <pre><code>.config(function($provide) {
    $provide.decorator( '$resource', [ "$delegate", function( $delegate ) {
      // here $delegate is the ResourceFactory which has 
      // already been linked to `$http` by a closure.
    }
  }
  </code></pre>