Reputation: 5114
I'm using angular 5 and I'm trying to lower the amount of parameters are injected in my classes. I'm not looking to discuss if service locator is an anti-pattern or not, just understand if angular/typescript would allow me to do that, please.
I use service locator for that quite often, but there's one case I can't figure out how to solve and the few questions I read about generic injection did not help much :/
Here's my case:
export abstract class BaseComponent<T extends BaseModel> {
protected recordId?: number = undefined;
protected alertService: AlertService;
protected translateService: TranslateService;
protected router: Router;
protected constructor(
protected activatedRoute: ActivatedRoute,
protected store: BaseCrudStore<T>,
protected baseType: { new(): T; }
) {
this.record = new baseType();
this.alertService = ServiceLocator.injector.get(AlertService);
this.translateService = ServiceLocator.injector.get(TranslateService);
this.router = ServiceLocator.injector.get(Router);
//...
}
}
I'd like BaseCrudStore
to also be resolved using service locator instead of injecting it through the constructor. Is there a way to accomplish this? Is there a way to get my store using the service locator? As you can see, the BaseCrudStore
is also generic and the generic parameter is the same one of the BaseComponent
class.
So far I can't also fix injecting ActivatedRoute
. It does inject, but (very likely) because of angular's structure it does not represent the current route, which makes sense thinking how it is built. If you know how to also fix this :)
I appreciate any help on this... my code is working 100%, it's just something that's been bothering me for a few months and I couldn't fix it.
ServiceLocator init:
export class AppModule {
constructor(private injector: Injector) {
ServiceLocator.injector = this.injector;
}
}
Thanks!
Upvotes: 1
Views: 1474
Reputation: 348
If you already have an injector in your environment, you can try something like this:
protected store: Store<T>;
protected constructor() {
this.store = AppInjectorService.injector.get<Store<T>>(Store);
}
Tested on Angular 6.
Upvotes: 6