If I have an Angular Module A that depends on a certain service S. But instead of implementing the service directly, I want to deal with an interface I and let the consumer of A pass the actual implementation when importing it. The implementation will be an Angular service decorated with @Injectable and has its own dependencies.
Is that feasible in Angular? if yes, what are the steps to implement it?
To archive this, you could use abstract classes instead of interfaces to make the implementations exchangeable:
app/
├── foo.service.ts
├── foo/
│ ├── abstract-foo.provider.ts
│ ├── foo.module.ts
│ ├── foo.component.ts
├── app.module.ts
Now the following files:
// foo.service.ts
@Injectable()
export class FooService extends AbstractFooProvider {
ctor(private _fooDependency: SomeOtherFooService){}
foo(): boolean {
return this._fooDependency.isFoo();
}
}
// foo.module.ts
@NgModule({
declarations: [FooComponent],
exports: [FooComponent]
})
export class FooModule {
static withConfiguration(implementationProvider: Provider): ModuleWithProviders {
return {
ngModule: FooModule,
providers: [implementationProvider]
};
}
}
// abstract-foo.provider.ts
export abstract class AbstractFooProvider {
foo(): boolean;
}
// foo.component.ts
@Component({})
export class FooComponent {
ctor(private _fooProvider: AbstractFooProvider){}
}
// app.module.ts
export const FOO_PROVIDER : ClassProvider = {
provide: AbstractFooProvider,
useClass: FooService
};
@NgModule({
imports: [
FooModule.withConfiguration(FOO_PROVIDER)
]
})
export class AppModule {}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With