1

Background: I am building an Angular 2 application. I have a Interface that declares a few properties and a few functions. I have a Class that implements that Interface. I would like to pass the interface into constructors of other classes. I would like to make Angular automatically inject the concrete Class whenever the Interface is being required. I do not want to specify the injection of the concrete class in every constructor, I only want to specify the interface.

Here is a copy of my Interface:

export interface IAuthSystem {    
    isAuthenticated: Boolean;    
    getCurrentUser(): User;     
}

Here is a simplified version of my Class that implements the Interface:

@Injectable()
export class FirebaseAuthSystem implements IAuthSystem {
  public isAuthenticated: Boolean = false;
  public getCurrentUser(): User {
     return new User();
   }
}

Here is a simplified version of a constructor from another class, in which I'd like for the FirebaseAuthSystem class to be automatically (and cleanly) injected into the authSystem parameter.

export class LoginPage {

  constructor(
    public navCtrl: NavController, 
    public navParams: NavParams, 
    public authSystem: IAuthSystem) {...

I've tried to use the Angular 2 Providers (in app.module.ts). But the provider doesn't seem to support interfaces. When I use this:

providers: [    
    { provide: IAuthSystem, useClass: FirebaseAuthSystem  },        
  ]

I get an error saying that "IAuthSystem only refers to a type, but is being used as a value here". I thought I had the the two properties switched around (provide and useClass), but I still get the same error. I've also tried to use useExisting, but I get same error.

I've read a lot of online material about Angular 2 and Dependency Injection, but have failed to use any of the material(s) to fulfill this scenario.

Steve Kennedy
  • 5,312
  • 3
  • 26
  • 41
  • Did you look at the section 'class-interface' of angular.io cookbook on Dependency Injection? It is this link https://angular.io/docs/ts/latest/cookbook/dependency-injection.html – Picci Mar 14 '17 at 05:58
  • @peeskillet You're right. I'm going to mark this question as duplicate. The OP of that question was working with mocking and unit test (I am not). But the accepted answer was relevant to my question - interfaces simply cannot be used as valid Provider Tokens. Future readers should consider using OpaqueToken - which I tried and abandoned because it forced me to specify injection concerns in the constructor signature. I replaced my interface with an abstract class with completely abstract members. This allowed me to use Provider Tokens in app.module.ts to inject my concrete class at run-time. – Steve Kennedy Mar 14 '17 at 18:44

0 Answers0