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.