What is multi provider in angular2
Asked Answered
W

4

74

I understand that provider is for getting service from another class but what is multi-provider and token thing?

And also when we do multi=true ?

provide(NG_VALIDATORS, { useExisting: class),    multi: true })
Williswillison answered 1/7, 2016 at 11:45 Comment(0)
L
69

multi: true means that one provider token provides an array of elements. For example all directives for router support routerLink, router-outlet are provided by ROUTER_DIRECTIVES.
If a new provider is registered with the token ROUTER_DIRECTIVES, then it overrides the previously registered directives. If multi: true (on the first registered and the new provider) is set, the new directives are added to the previously registered directives instead of overriding.

When ROUTER_DIRECTIVES is injected (constructor(@Inject(ROUTER_DIRECTIVES) directives) {}) an array of directive instances is injected. It usually doesn't make sense to inject ROUTER_DIRECTIVES. I used it just as an example because it is multi: true.

Lewallen answered 1/7, 2016 at 11:59 Comment(6)
Could you give an example of when it would be usefull por favorWenonawenonah
See the example in #39034335 where multiple factory functions can be provided under APP_INITIALIZERS and Angular will call each of them (in the sequence they were provided) and waits for the returned Promise.Euphoria
NG_VALIDATORS as an example. They are: required, min, max, email...Deneendenegation
This can be relevant examples for multi: true providers: [{ provide: HTTP_INTERCEPTORS, useClass: CustomHttpInterceptorService, multi: true } ]Hatteras
If multi: false provider is provided by component, will it override previous providers for same token for subtree of components under it or globally?Kunzite
@Kunzite For components under it is my guess, but you'd need to verify yourself to be sure.Euphoria
N
13

What is a multi-provider?

Provider is defined here.

https://angular.io/api/core/Provider

Basically, the provider describes how an injector is configured. So a multi-provider is you using multiple providers instead of a single provider, for instance

providers: [
 { provide: TOKEN1 , useClass: ClassName1},

 { provide: TOKEN2 , useClass: ClassName2}
]

In the above scenario, instances of both classes are created for the given token. This is then available for dependency injection (In the constructors of the particular classes.)


What is Token?

Token is the lookup key for locating the dependency value, for instance let’s take as follows…

then the lookup key is the TYPE of className, and the dependency value is the INSTANCE of its class.

providers: [ClassName]

In the following example, the TOKEN1, and TOKEN2 are the lookup keys, and the dependency values are the instance of both classes.

providers: [
 { provide: TOKEN1 , useClass: ClassName1},

 { provide: TOKEN2 , useClass: ClassName2}
]

When do we use multi=true ?

The multi is useful when you register multiple providers for the same token. Let’s say in the following example, then the last provider is injected because it’s used at the end, meaning

you won’t be able to use a ClassName1 instance. So what you can do is to use multi=true, and this signals Angular to register multiple providers for the SAME token. So this injects an ARRAY of values.

What is the value? the value is the INSTANCE of the classes.

providers: [
 { provide: TOKEN , useClass: ClassName1},

 { provide: TOKEN , useClass: ClassName2}
]

So the rule of thumb is if you are registering multiple providers for the same TOKEN then always use multi=true to avoid the first provider from not being injected. When it's injected, you can use it in the constructor of the class.

NOTE: I am not an expert in this area. So if you saw any problem please let me know.

Naraka answered 26/11, 2020 at 1:4 Comment(0)
I
12

Using multi: true tells Angular that the provider is a multi provider. As mentioned earlier, with multi providers, we can provide multiple values for a single token in DI.

Usages:

If we have a couple of directives that should automatically be available in our entire application without anyone having to define them in component decorations, we can do that by taking advantage of multi providers and extending what is being injected for PLATFORM_DIRECTIVES.

@Directive(...)
class Draggable { }

@Directive(...)
class Morphable { }

@Component(...)
class RootCmp { }

and

// at bootstrap
bootstrap(RooCmp, [
  provide(PLATFORM_DIRECTIVES, {useValue: Draggable, multi: true}),
  provide(PLATFORM_DIRECTIVES, {useValue: Morphable, multi: true})
]);

Details

Ingulf answered 1/7, 2016 at 11:52 Comment(5)
what does it mean provide multiple values for single token in DIWilliswillison
See example code. Injecting an array of directives/values in code .the detail link has examples and explanationIngulf
What does it mean if function declared like this : private get isReverse() what is get keywordWilliswillison
It is property syntax of typescript see https://mcmap.net/q/53351/-get-and-set-in-typescriptIngulf
you registers your services to a token Service provider (ex: NG_VALIDATORS) for events. Observer uses the token service to get all registers service pass events to them (ex: Form will get all services from NG_VALIDATORS then pass event to all validations)Glycerin
H
2

From the docs:

Creates multiple providers matching the same token (a multi-provider). Multi-providers are used for creating pluggable service, where the system comes with some default providers, and the user can register additional providers. The combination of the default providers and the additional providers will be used to drive the behavior of the system.

Source

Headpin answered 1/7, 2016 at 11:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.