vicmac
vicmac

Reputation: 675

More than one different Injected Instance of an object in Angular 2

I have a class like this

  import {Injectable } from '@angular/core';
  @Injectable()
  export class Address {
        street: string;
       ... some other attributes

  }

And a class like this

  import {Injectable } from '@angular/core';
  import { Address } from './address';

   @Injectable()
   export class Company {
         name: string;
         constructor(public address: Address) {}
   }

And I use the above classes like this

  import { Injectable } from '@angular/core';
  import { Address } from './address'; 
  import { Company } from './company';

   @Injectable()
   export class Employee {
      name: string;
      lastName: string;

      constructor(public address: Address,
                  public company: Company) {}
   }

Now, I use the Employee class in a component like this

  import {Component } from '@angular/core';
  import { Employee } from '../model/employee';

  @Component({
   moduleId: module.id,
   selector: 'my-employee',
   templateUrl: '../views/employee.html
  })
  export class EmployeeComponent {
      constructor(public employee: Employee){}

   ... some other stuff;
 }

My questions are:

1.- Why I'm getting the same Address object for both the company and the employee address objects? 2.- How can I get different instances of Address object?

3.- I know, I can make a new instance of Address in the constructor of the EmployeeComponent, with the new operator, and then assign it to the let's say employee.address, but then, what is the purpose of DI in Angular 2?

Upvotes: 1

Views: 1635

Answers (1)

Adnan A.
Adnan A.

Reputation: 1982

1.- Why I'm getting the same Address object for both the company and the employee address objects?

That because you're using the same injector. Injector tree maps the component tree, which means that each component has it's own injector and it will try to resolve its dependencies using it, and if that's not possible, it will bubble up the resolution up to the root injector. In this case, since you haven't included your models in component providers (your injector is essentially empty) it will use root injector and pass the same instance of your injectables all over the application. Step by step:

  1. Your EmployeeComponent constructor requests Employee injection
  2. Request bubbles up to the root injector (there is nothing in component injector)
  3. Injector tries to create new Employee
  4. Employee constructor request Company and Address injection
  5. Injector creates new Address
  6. Injector tries to create Company
  7. Company requests Address injection
  8. Injector injects already resolved Address object from step 5.
  9. Injector creates Company
  10. Injector creates Employee
  11. Injector injects Employee into the Employee component

NOTE: Having injector on the component level won't help - it would still be the same address for all objects where Address is injected inside that components scope.

2.- How can I get different instances of Address object?

You might want to take a look at this question. Also, you can take a look at the documentation.

3.- I know, I can make a new instance of Address in the constructor of the EmployeeComponent, with the new operator, and then assign it to the let's say employee.address, but then, what is the purpose of DI in Angular 2?

The purpose is as same as in any other language. It might not be clear, as interfaces are not used in a same way as in C# or some other language, but the point is to reduce the dependency on behaviour from some concrete object to abstract object that can be injected into the class at runtime. It's not meant for POJOs, data contracts and, in most cases, business domain model. It's meant for classes that excercise behaviour that can be abstracted and injected into a number of different software components, so they can use this behaviour in runtime, but not depend on it's concrete implementation.

Upvotes: 3

Related Questions