Search code examples
angularangular-injector

Can I inject a custom (Path)LocationStrategy?


I'm using a custom PathLocationStrategy:

@Injectable() // also tried @Injectable({providedIn: 'root'})
export class CustomPathLocationStrategy extends PathLocationStrategy {

    constructor() {
        console.log('CustomPathLocationStrategy constructor');
    }

    ....
}

To let Angular know about my own implementation in app.module.ts:

providers: [ 
{
  provide: LocationStrategy,
  useClass: CustomPathLocationStrategy
}

This is working fine.

But now I try to inject CustomPathLocationStrategy into a component:

@Component(...)
export class AppComponent {

    constructor(private custom: CustomPathLocationStrategy) {}

The browser console now prints the "CustomPathLocationStrategy constructor" message twice: a new object is created for CustomPathLocationStrategy. This one is different from the one that is used to implement the LocationStrategy.

Am I not supposed to inject CustomPathLocationStrategy in my own components or other services? Or am I doing it wrong?


Solution

  • When you add a provider. The provide property defines the InjectionToken or key to identify that provider. The useClass, useFactory,... only tells the injector how to create that dependency if someone ask for it.

    So when you add a provider like this:

    {
      provide: LocationStrategy,
      useClass: CustomPathLocationStrategy
    }
    

    You are basically telling the app, that if some element asks for a LocationStrategy, it should use the CustomPathLocationStrategy class to create the dependency and give it back, or if it was already created give that existing instance back.

    So in your component, you need to 'ask' for a LocationStrategy, and the DI system will give you back the instance of the CustomPathLocationStrategy you've told it to use.

    @Component(...)
    export class AppComponent {
    
      constructor(private locationStrategy: LocationStrategy) {}
    
      ...
    
    }
    

    Cheers