1

I'm developing a package that is used by two projects in my company. In project A and only there we got a message service that is provided in core.module like this:

        {
          provide: 'MESSAGE_SERVICE',
          useClass: MessageService
        }

In my component, I need to inject this service. I'm doing it using injector. However the method get that accepts a string as a parameter is deprecated so I cannot use it, although it works. When I try to use a new API with InjectionToken I always get undefined. Here's my code:

  protected messageService: any;

  constructor(protected injector: Injector) {
    const messageServiceInjectionToken = new InjectionToken('MESSAGE_SERVICE');
     // i get null
    this.messageService = this.injector.get<any>(messageServiceInjectionToken, null, InjectFlags.Optional);
    // It works but method is deprecated
    this.messageService = this.injector.get('MESSAGE_SERVICE', null);
    // It works but I cannot use MessageService class directly as it is not present in application B
    this.messageService = this.injector.get(MessageService);
  }

What is the proper way to get my service without using direct imports of said class? I thought of creating a mock class in project B so I would be able to use MessageService class. However, I'd like to know if there's a better way.

EDIT

The shared service is just a base class to other implementations, it is provided using a factory so there's not dependency injection in it. This is how it is provided:


export function parentServiceFactory(platformService: PlatformService, injector: Injector) {
  if (platformService.isIOS) {
    return new IosChildService(injector);
  }

  if (platformService.isAndroid) {
    return new AndroidChildService(injector);
  }

  return new DesktopChildService(injector);
}

@NgModule({
providers: [
    {
      provide: ParentService,
      useFactory: parentServiceFactory,
      deps: [PlatformService, Injector]
    }
]
})
export class SharedModule {}

2 Answers 2

2

The purpose of that injection token is to be able to not use the injector.

Instead =, use this syntax

constructor(@Inject('MESSAGE_SERVICE')protected service: YourInterface)

Although if you make a service, I don't see the point of using an injection token.

Sign up to request clarification or add additional context in comments.

9 Comments

I'd like to avoid this approach as my class is inherited by other classes. That's why I am using a injector.
And how does that prevent you from using this approach, or the default one with @Injectable ?
It does not it is just mundane work to pass message service to parent component in every child
@karoluS so what prevents you from using this method or the default one again ?
I've made an edit to the original question explaining why it would not work in my scenario.
|
0

You can create an angular library and then use it in any number of projects

Here's how to create an angular2 library https://makina-corpus.com/blog/metier/2017/how-to-create-an-angular-library

with angular-cli https://medium.com/@nikolasleblanc/building-an-angular-4-component-library-with-the-angular-cli-and-ng-packagr-53b2ade0701e

2 Comments

It would not work in application B where MessageService is not available.
Consider upvoting the answers that are the same as the one you are about to write, as per SOF best practices

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.