« Back to Blogs

Dependency injection in Ember js(3.5 V).

What is dependency injection?

In software engineering, Dependency Injection is a practice where objects are designed in a manner where they receive instances of the objects from other pieces of code, instead of constructing them internally.

In simple words, let’s say When you are working with object-oriented programming and you are going to build an object at that time you need some functionality of another object. Dependency injection will help you to inject dependent objects on your object. Now you can use the functionality of another object in your object. You can easily understand from the below image.

Dependency injection in Ember js.

Ember application used dependency injection design pattern to declare and instantiate objects of classes and manage dependency between them. Application and application instances serve a role in Ember's DI implementation.

There are two ways to inject dependency on your object.
  1. Using factory registration and initializer.
  2. Ad Hoc Injections.
1. DI Using factory registration and initializer.

To inject dependency using factory registration and initializer you need to follow the below steps.

  Step1: Instantiate Application:

  • An Application provides a registry for dependency declarations. You can register factories to the Application as well as you can define rules for DI.
  • Each Ember app has only one Application object. The very first thing you should do in your application is to create the instance for Application in the app.js file.
    app/app.js
    import Application from '@ember/application';
    var app = Application.create();
  • Application.create() will automatically initialize your application by calling the Application.initialize() method.

  Step2: Factory Registrations:

  • Factory specifies all application parts such as route, templates, component, etc. with a particular key.
  • Key has a two-segment which is split by (:). The First segment is the factory type and the second one is a factory name.
  • To register the factory with the application, you can use the register method of the Application object.
  • As Example, Let's create a Ember object with name Action.
    app/utils/Action.js
    import EmberObject from '@ember/object';
    var Action = EmberObject.extend({
      perform(m) {
        console.log("dance");
      }
    });
    export default Action;
  • Let's register Action object with the index route.
    • To create initializers of Action object you can fire below command.
      ember generate initializer Action

        For register Action object with index route, you need to add a highlighted line on your file.

      app/initializers/Action.js
      impoer Action from '../utils/Actions.js';
      export function initialize(application) {
       app.register('utils:action',Action);
      };
      • Registering Singletons vs. Non-Singletons
      • By default, registration is done in the form of a singleton. It means instance will create only one time at first lookup, and the same instance will be returned where it will need.
      • If you want to fresh object to be created for every time then register your factory with non-singleton using singleton: false option.
        application.register('utils:action', Action, { singleton: false });
  • There is also a two way to inject registered object on your app.
    1. Factory Injections using inject method at declaration time.
    2. Factory Injections using Factory Instance Lookups at run time

        Option 1: Factory Injections using inject method at declaration time.

          Once the factory is registered with application than you can inject it where it is needed using      ember dependency injection.

          Example :

          Initialize method call automatically when Application.create() method called.

      app/initalizers/Action.js
      export funtion initialize(application) {
        application.register('utils:action', Action);
        application.inject('controller, 'action', 'utils:action');
      };
      

          Now you can use Action object in all controllers of application using action property.

      app/controllers/index.js
      import controller from '@ember/controller';
      export default Controller.extend({
       activate: function() {
         this.get('action').perform();
       }
      });

          If you want to inject an object on a particular one controller then follow the below method.

      app.inject('controller.index', 'action', 'utils:action')

          Now you can use action object in only index controller of application using action property

          Option 2. Factory Injections using Factory Instance Lookups at run time.

          To fetch the instantiated factory from running the application, you can call the lookup method      on the application object. It will return an object of the factory.

      applicationInstance.lookup('factory-type:factory-name);
      

          getOwner method provide return application instance for the Application, so we can use this      method on route, component, controller, etc to retrieve application instance at runtime.

      app/components/index.js
      
      import Component from '@ember/component'; 
      import {getOwner} from '@ember/application'; 
      
      export default Component.extend({
        getActions: function() {
          var applicationInstance  = getOwner(this);
          return applicationInstance.lookup('utils:Action');
        }
       actions: {
        click() {
          var actions = this.getActions();
          this.actions.perform();
        }
       }
      });
      
2. Ad Hoc Injections:

We can also inject dependency directly on Ember classes using inject. Currently, we can only inject the dependency of controller and service with this method.

    Example :

app/services/message.js
import Service from '@ember/service';
export default Service.extend({
   send() {
    console.log(“Message sent”);
   }
});
app/components/user.js
import Component from '@ember/component'; 
import { inject } from '@ember/service'; 
export default Component.extend({ 
  messageService: inject('message'),
  didInsertElement: funcion() {
    this.get(“messageService”).send();
  }
});

Conclusion:

Ember js used powerful and efficient DI for code reusability and also its make more powerful to your app. There are many ways to inject your dependency to any factory of the app, which I mention you were you looked above, I hope this is useful for you.

 

Comments
No comments yet. Be the first.
contact-us Request a callback