Angular 6 service with interface

前端 未结 4 1266
旧时难觅i
旧时难觅i 2021-01-02 04:00

I am building an application with Angular (6.0.7) and I am trying to create a service with the new:

@Injectable({
  providedIn: \'root\'
})


        
相关标签:
4条回答
  • 2021-01-02 04:10

    I think you can't use typescript interfaces for dependency injection as typescript interfaces don't exist at runtime (only for typesafety at compile time).
    I would suggest using an abstract class for it.

    EDIT: It seems you can use useClass in the first parameter of @Injectable, not as a second like your example. Combining that with @k0zakinio's answer results in:

    @Injectable({
      providedIn: 'root',
      useClass: environment.concrete,
      deps: []
    })
    export abstract class SessionStorage { }
    

    It also seems you need to declare your dependencies via deps or inject, checkout this github issue. I hope this time my answer is of more help.

    0 讨论(0)
  • 2021-01-02 04:25

    This can be done with InjectionToken, which is a replacement for the obsolete OpaqueToken

    export const AuthenticationProvider = new InjectionToken(
      "AuthenticationProvider",
      { providedIn: "root", factory: () => new CognitoAuthenticationProvider() }
    );
    
    ...
    
    @Injectable()
    export class CognitoAuthenticationProvider implements IAuthenticationProvider {
    
    ...
    
    @Injectable({
      providedIn: "root"
    })
    export class AuthenticationService {
      constructor(
        @Inject(AuthenticationProvider)
        private authenticationProvider: IAuthenticationProvider,
        private http: HttpClient
      ) {}
    
    0 讨论(0)
  • 2021-01-02 04:27

    I used something like the following to solve this

    app.module.ts

    providers: [
      { provide: AlmostInterface, useClass: environment.concrete }
      ...
    ]
    

    AlmostInterface.ts

    export abstract class AlmostInterface {
       abstract myMethod();
    }
    

    MyConcrete.ts

    export class MyConcrete implements AlmostInterface {
       myMethod() { ... }; // implementation
    }
    
    export class MyConcreteAlternative implements AlmostInterface {
       myMethod() { ... }; // implementation
    }
    

    environment.ts

    export const environment = {
      production: false,
      concrete: MyConcreteAlternative
    };
    

    environment.prod.ts

    export const environment = {
      production: true,
      concrete: MyConcrete
    };
    
    0 讨论(0)
  • 2021-01-02 04:27

    You can use something like -

    [{ provide: InterfaceName, useClass: ClassName}]
    
    0 讨论(0)
提交回复
热议问题