Thiago Caramelo
Thiago Caramelo

Reputation: 309

AngularJS's $injector

Why or why not should I inject angular's $injector itself instead of injecting separated, and named, dependencies as parameters to a controller's constructor function ?

Upvotes: 1

Views: 66

Answers (1)

Robba
Robba

Reputation: 8324

While using the $injector service would work just fine, I can think of two reasons why I personally would never do it:

  1. It's a hassle that's totally unnecessary
  2. It obscures what the dependencies for a component or are.

To illustrate, see the difference between these two:

app.controller('myController', function($scope, myService) {
})

and

app.controller('myController', function($injector) {
    var $scope = $injector.get('$scope');
    var myService= $injector.get('myService');
})

The two examples above do the same thing, but I believe the first is much clearer in intent.

Do note however that there are situations where using the injector directly may be neccesary: when there's a circular dependency. Take this (silly) example:

app.factory('service1', function(service2) {
    return {
        someFunction: function() {
            return service2.otherFunction();
        },
        otherFunction: function() {
            return 'result from service 1 other function';
        }
    }
});
app.factory('service2', function(service1) {
    return {
        someFunction: function() {
            return service1.otherFunction();
        },
        otherFunction: function() {
            return 'result from service 2 other function';
        }
    }
});

This would return in an error since the injector can't create service1 and service2 before the other. In this case you might do the following:

app.factory('service1', function(service2) {
    return {
        someFunction: function() {
            return service2.otherFunction();
        },
        otherFunction: function() {
            return 'result from service 1 other function';
        }
    }
});
app.factory('service2', function($injector) {
    return {
        someFunction: function() {
            var service1 = $injector.get('service1');
            return service1.otherFunction();
        },
        otherFunction: function() {
            return 'result from service 2 other function';
        }
    }
});

Note how service1 is no longer injected into service2, but is only asked from the injector when the relevant function is called, at which point there is no longer a race condition.

Upvotes: 1

Related Questions