Over a million developers have joined DZone.

Angular 2 Bits: Unified Dependency Injection

· Java Zone

Discover how powerful static code analysis and ergonomic design make development not only productive but also an enjoyable experience, brought to you in partnership with JetBrains

Angular 1.x has two APIs for injecting dependencies into a directive. These APIs are not interchangeable, so depending on what you are injecting, you need to use one or the other. Angular 2 unifies the two APIs, making the code easier to understand and test.

Angular 1.x

Let’s start with a simple example: a directive autocompleting the user input.

<input name="title" autocomplete="movie-title">

The autocomplete directive takes the user input, and using the autocompleter service object, gets matching movie titles from the backend.

module.directive('autocomplete', ["autocompleter", function(autocompleter) {
      return {
        restrict: 'A',
        link: function (scope, element, attrs) {

Note, we have to use two mechanisms to inject the autocompleter and the element.

  • The autocompleter service is injected into the directive factory function, and it is done by name.
  • The element and the attributes are injected into the link function. This is done by position, which forces us to pass in scope, even though we may not need it.

Angular 2

Now, contrast it with the Angular 2 way of defining the same directive.

@Decorator({selector: '[autocomplete]'})
    class Autocomplete {
        constructor(autocompleter:Autocompleter, el:NgElement, attrs:NgAttributes){

Or if you prefer ES5

function Aucotomplete(autocompleter, el, attrs) {
    Aucotomplete.annotations = [new Decorator({selector: '[autocomplete]'})];
    Aucotomplete.parameters = [[Autocompleter], [NgElement], [NgAttributes]];

In Angular 2 the autocompleter, the element, and the attributes are injected into the constructor by name.

Hierarchical Injectors

How is it possible? Should not every instance of the directive get its own element? It should. To enable that the framework builds a tree of injectors that matches the DOM.

        <input name="title" autocomplete="movie-title">
        <input name="actor" autocomplete="actor-name">

The matching injector tree:

Injector Matching Div
        |__Injector Matching Movie Title
        |__Injector Matching Actor Name

Since there is an injector for every DOM element, the framework can provide element-specific information, such as an element, attributes, or a shadow root.


In Angular 2 there is a single way to inject dependencies into a directive, regardless of what you inject: user-defined services, framework services, elements, attributes, or other directives.

Learn more about Kotlin, a new programming language designed to solve problems that software developers face every day brought to you in partnership with JetBrains.


Published at DZone with permission of Victor Savkin, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}