Reputation: 979
I have a module which should have injected a service depending on the router path, e.g.
for a path with /demo
it should have injected a DemoService
and for paths without /demo
it should have provided a UserService
.
How can I implement such functionality?
Of course I could inject both services and in the module itself determine whether it should use a DemoService
or a UserService
but then the module wouldn't be reusable in other apps.
Upvotes: 3
Views: 4568
Reputation: 1465
abstract class DataService {
abstract doSomething(): void;
}
class FactoryService {
activeService = new BehaviorSubject<DataService>();
getService(): Observable<DataService> {
return this.activeService.asObservable();
}
}
class DemoService extends DataService {
doSomething(): void {
console.log('DemoService');
}
}
class UserService extends DataService {
doSomething(): void {
console.log('UserService');
}
}
take the shared parts of an API of your services to an abstract class, so the consumers should rely on the interface.
DemoService
or UserService
define your provider as a factory e.g.providers: [{
provide: FactoryService,
useFactory: (route: ActivatedRoute) => {
const factoryService = new FactoryService();
const url = route['_routerState'].snapshot.url;
url.startsWith('/demo/')
? factoryService.activeService.next(new DemoService())
: factoryService.activeService.next(new UserService());
return factoryService;
}
deps: [ActivatedRoute]
}],
ServiceFactory
which should provide a proper serviceconstructor(private factoryService: FactoryService) {
this.factoryService.activeService.subscribe((activeService: DataService) => {
// Here you can now do stuff with an proper service
});
}
Hope, you've got the idea...
Upvotes: 4