angular 6 dependency injection

28,270

Solution 1

Basically you can use either, But as per new CLI provideIn will be automatically added while creating service

#providedIn

There is now a new, recommended, way to register a provider, directly inside the @Injectable() decorator, using the new providedIn attribute. It accepts 'root' as a value or any module of your application. When you use 'root', your injectable will be registered as a singleton in the application, and you don’t need to add it to the providers of the root module. Similarly, if you use providedIn: UsersModule, the injectable is registered as a provider of the UsersModule without adding it to the providers of the module.

This new way has been introduced to have a better tree-shaking in the application. Currently a service added to the providers of a module will end up in the final bundle, even if it is not used in the application, which is a bit sad.

For more information please refer here

Solution 2

As always when multiple solutions are available it depends on what you want to achieve. But the documentation gives you some directive to choose.

Sometimes it's not desirable to have a service always be provided in the application root injector. Perhaps users should explicitly opt-in to using the service, or the service should be provided in a lazily-loaded context. In this case, the provider should be associated with a specific @NgModule class, and will be used by whichever injector includes that module.

So basically you will use providedIn: 'root' for any services that are application wide. For other services keep using the old version.

Don't forget that on you already had the choice to provide service differently. For instance it's also possible to declare Injectable at component level (this doesn't change in V6).

  @Component({
    selector: 'app-my-component',
    templateUrl: './my.component.html',
    providers: [ MyService ]
  })

This way the service becomes available only in MyComponent and its sub-component tree.

Solution 3

If You are using angular 5+ developer, it will automatically create the injectable service when declared as providedIn: 'root', in this case you will not required to import the service in app.module.ts. You can directly use it in another component.

Share:
28,270
Hamed Baatour
Author by

Hamed Baatour

💻 Full Stack JS Developer & UI/UX Designer ⚡ currently working on InTab the fastest way to ship responsive CSS 💌 You can reach me on: [email protected]

Updated on October 02, 2020

Comments

  • Hamed Baatour
    Hamed Baatour over 3 years

    In the latest release of Angular 6, a service is registered in a module using the providedIn property in the service metadata:

    @Injectable({
      providedIn: 'root',
    })
    export class HeroService {}
    

    However the documentation still also refers to registering the service in the module providers array in the module metadata just like we did in Angular 5:

    @NgModule({
      providers: [HeroService],
    })
    export class AppModule {}
    

    So,

    • Which method should be used to make the injector aware of the service that it should inject?
    • Will the module providers array method be deprecated?
  • jonrsharpe
    jonrsharpe almost 6 years
    Also note if you don't mark quotes correctly it looks like plagiarism.
  • Pardeep Jain
    Pardeep Jain almost 6 years
    @jonrsharpe yes most of the content I copied , that's why posted link as well
  • Denis Itskovich
    Denis Itskovich almost 6 years
    Actually I find it very strange that service is aware of the modules using it, and not vice versa. How can such service be reusable? If I add a new module which needs to use the service, I need to change the service itself? It sounds rather ridicules
  • gawkface
    gawkface almost 6 years
    @DenisItskovich - a singleton reusable service need only be @Injectable({providedIn: 'root'... - this is also usable for service-to-service dependency (if not singleton, then DI in each component's providers array where it is to be reused). So basically as per another answer by JEY here, different options apply for different usecases
  • Yiping
    Yiping over 5 years
    @PardeepJain so @Injectable() will lead to providedIn:root added by default?
  • Pardeep Jain
    Pardeep Jain over 5 years
    @Yiping no, I am not sure but I don't think so. But after v6 whenever you create service using command line (CLI) angular will automatically add providedIn and set it to root by default.
  • Tuan-Tu
    Tuan-Tu over 3 years
    For reference, here are some updated links to documentation, as the quote seems to come from the blog article and the link the the documentation is now incorrect angular.io/guide/…
  • Pardeep Jain
    Pardeep Jain over 3 years
    @Tuan-Tu thank you for reference, I have updated the answer with the link you suggested.