6

angular: 2.0.0-beta.9

Is it possible to inject a non @Injectable class into a component ? For example, this class could come from a Third party library.

plone1
  • 666
  • 1
  • 10
  • 15

3 Answers3

9

Yes, it's possible. In fact the @Injectable decorator isn't to specify that a class is injectable into other ones but that you want to inject something in it at the level of its constructor.

If you don't want to inject something in your class, it's not mandatory to add the @Injectable decorator. This class can be injected into other ones.

I think that this Github issue could help you:

What is important here is to understand the difference between decorators and annotations. Here is a great article on this subject:

Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
2

I think yes it is possible. I have tested it without @Injectable decorator and it works fine.

plunker

AuthService.ts

 import {Injectable} from 'angular2/core';
 import {Http, Response,HTTP_PROVIDERS} from 'angular2/http';
 import 'rxjs/Rx';
 import {Observable} from 'rxjs/Observable';

 export interface sharedObject{
  firstName:string;
  lastName:stirng;
 }


export class AuthService{
  user:sharedObject;
  constructor()
  {
    console.log('AuthService started')
    this.user={firstName:"micronyks",lastName:"shah"};
  }

  change() {
    console.log('change to angular2');
    this.user.firstName="micronyks1";
    this.user.lastName="shah1";
  }     
}

If you wonder, because some class, use DI in the constructor and do not use @Injectable(). Because this decorated @, for example @Components.

The HeroesComponent has an injected dependency too. Why don't we add @Injectable() to the HeroesComponent?

We can add it if we really want to. It isn't necessary because the HeroesComponent is already decorated with @Component. TypeScript generates metadata for any class with a decorator, and any decorator will do.

For more info you can read this link Angular page

Angel Angel
  • 19,670
  • 29
  • 79
  • 105
micronyks
  • 54,797
  • 15
  • 112
  • 146
  • Oh thanks for the suggestion. But now if someone likes my answer would see your comment too and will get to the right direction :-) – micronyks Mar 18 '16 at 10:36
  • Oh great man ! Why don't you edit my answer and link to angular.io. I will accept your edit :-). I'm in some work so can't do it as expected immediately. :-) – micronyks Mar 18 '16 at 10:47
  • no problem but surely you can do better than me, because my English is very bad, you can review and edit if you do not like good luck – Angel Angel Mar 18 '16 at 11:06
  • 1
    I dont have an option to give you +1 else I would have done it. But many thanks for indicating the right thing :-) – micronyks Mar 18 '16 at 11:14
1

If the class has dependencies you still can use it in DI. Just provide a factory for it

If you want to be able to inject a class that itself has dependencies (constructor arguments) but don't want or can't apply @Injectable(), then you can use a factory instead

bootstrap(AppComponent, [
    SomeDep, 
    provide(SomeType, {useFactory: (dep) => new SomeType(dep), 
        deps: [SomeDep]})
]);

You can create variables for such providers to make them easily reusable without this cumbersome declaration (like for example HTTP_PROVIDERS)

export const SOME_TYPE_PROVIDERS: any[] = [
  SomeDep, 
  provide(SomeType, {useFactory: (dep) => new SomeType(dep), 
      deps: [SomeDep]})
];

and then use it like

bootstrap(AppComponent, [SOME_TYPE_PROVIDERS]);
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567