I am building an application with Angular (6.0.7
) and I am trying to create a service with the new:
@Injectable({
providedIn: \'root\'
})
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.
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
) {}
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
};
You can use something like -
[{ provide: InterfaceName, useClass: ClassName}]