简体   繁体   中英

What is the difference in Angular2 between inject a provider in @Component and @Module?

In angular2 it is possible to define the providers in a @Component element like

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css'],
  providers : [ DataService ]
})
export class HomeComponent implements OnInit {

...
}

and also in a

@NgModule({
  declarations: [
    ...
  ],
  imports: [
    ...
  ],
  providers: [ DataService ],
  bootstrap: [AppComponent ]
})
export class AppModule { }

what is the difference between define the provider in the @NgModule or in a @Component? and If I should choose one of two, what should be the better place to define the provider ?

@NgModule: service will be a singleton inside the child components of that module that injects the service (inside the constructor).

@Component: service will be a singleton inside the component and its child components.

Source: https://angular.io/docs/ts/latest/guide/dependency-injection.html#when-to-use-the-ngmodule-and-when-an-application-component-

When to use the NgModule and when an application component?

On the one hand, a provider in an NgModule is registered in the root injector. That means that every provider registered within an NgModule will be accessible in the entire application.

On the other hand, a provider registered in an application component is available only on that component and all its children.

Angular application is a tree of components. Each component has its own injector. Hence, you have a tree of injectors. Suppose, you have the following setup:

    AppComponent
  /            \
 C1            C2
              /  \
            C3   C4

Now, if you define a provider inside any @NgModule (except the one this is lazy loaded), you'll be able to access that provider in any of the components ( C1, C2, C3, C4 ). If you define a provider in @Component , say in C2 , only C2 and its children C2 will be able to access that provider. But even this is configurable. You can use additional decorators like @Self to search for a dependency declared by the component.

The difference is the scope.

Actually

  • "injecting" is adding a parameter to a constructor.
  • Adding it to providers: [...] is "providing"

providing at a component will result in multiple instances

If a provider is registered in a component, you get potentially as many instances of the providers value (service instance) as there are component instances. "potentially" because if there is a provider, but it is never actually injected, then no instance will be created.

looking up providers

When DI creates a component, directive, pipe, or service instance, it checks the current injector for providers the constructors parameters. If the injector doesn't have a provider, it checks parent injectors until it finds a provider or there are no parent injectors.

injector hieararchy Providers registered in (non-lazy loaded) modules are added to the root injector. Lazy loaded module's injector is a child injector. The AppComponent s injector is also a child injector of the root injector. Every child component or directive gets a child injector of the parent components injector.

adding a provider to a component or directive

This means, when you provide a service on a component, this component and its descendant components get an instance from the provider registered with this component. Everywhere else no provider will be found and therefore instance creation will fail.

If there are multiple instances of this component, then each component (with it's descendants) will get a different instance of this service.

adding a provider to a module

If a provider is registered in @NgModule() (non-lazy loaded) every component and service will find this provider, and the same instance will be injected everywhere.

adding a provider to a lazy-loaded module

If a provider is registered in @NgModule() of a lazy loaded module, then the service will only be available for components and services loaded by this module.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM