Last Updated: February 25, 2016
·
1.31K
· ram9cc

Ember's Dependency Injection (on a type of object)

Often when developing a system, application, or library - there are going to be some kind of cross cutting concern that you will want to share among objects - much before you even know what all the objects in the system will be.

Ember understands this need and has build into the framework 'initializers' that give you the ability to do dependency injection on a whole class of objects.

Take a gander at this:

Ember.Application.initializer({
  name: 'racecar',
  initialize: function( container, application) {
    var Racecar = Em.Object.extend({
      start: function() {console.log("start your engine")}, 
      race:  function(){return "vroom"}
    })

    application.register("session:racecar",Racecar);
    application.inject("route","racecar","session:racecar")
  }
})

This in an initializer that has created a Class of objects and registered it with a name 'session:racecar'. This name was not chosen for any particular reason - though it seems
that by using the format "type:name" i'm also declaring 'session' to be a type of object in my system. (the use of the word 'type' will be explained below - in the context of inject)

The 'register' method defaults to using a singleton implementation, it's going to invoke 'create' on the Racecar 'class' at first request for the object. The 'register' method has a couple of options as specified here : http://emberjs.com/api/classes/Ember.Application.html#method_register

The 'inject' method can be used on a specific factory (this term is used to refer to any object with a create method) like 'route:application' or 'controller:index' - or an entire set of types 'controller' , 'route' , etc.

Inject the part that actually binds a registered object factory (injectionName) with a specific property name and (property) and puts it into a factory or type (factoryNameOrType) as specified here : http://emberjs.com/api/classes/Ember.Application.html#method_inject

Now that my initializer has been setup - I can create my ember application and expect that my 'racecar' property will exist.

App = Ember.Application.create();

App.Router.map(function() {
  // put your routes here
});

App.IndexRoute = Ember.Route.extend({
  model: function() {
    this.racecar.start()
    return ['red', 'yellow', 'blue', this.racecar.race()];
  }
});

In the above example 'this.racecar' will refer to the singleton instance of Racecar associated with the name 'session:racecar' in my application.

Here is some more background details for the keen reader.
https://en.wikipedia.org/wiki/Dependency_injection
https://en.wikipedia.org/wiki/Dependency_inversion_principle