Currently, the framework authorizes only a single registration per type. Calling twice do.ProvideValue[int](i, ...) will trigger an error. In that situation, the invocation is much simpler because we can find at most 1 service.
However, starting with v2, we will support service aliasing, either via explicit declaration (do.As[Intial, Alias](...)) or via implicit invocation (do.InvokeAs[Alias](...)), which loads the first service implementing the Alias interface.
Note: currently, a developer can override a service using do.OverrideXXX(...). It has been suggested as a hot-service replacement in unit tests, and should be combined with .Clone() method of RootScope. If the override is done after original service invocation, the service is replaced, but not unloaded/shutdowned.
Multiple contributors asked for an improvement: #33 #75 #45 #52 #117
Poke @matdurand @svenwltr @danilobuerger @d-enk @mbark @GregPja @Jictyvoo
Checklist:
a- how to name and store the services in the DI container, while preventing collision?
b- multiple services on registration via do.As
c- multiple services on invocation via do.InvokeAs
d- multiple services on do.InvokeStruct shadow resolution
e- how to deal with post-invocation registration ?
a) Collision in container
Naming: I would suggest storing all IService as a single service of type []IService. Then, this service would be invoked with do.Invoke[[]IService], and do.Invoke[IService] would point to either none or the provided service.
1- Inject multiple services of the same type (eg: HttpRoute) and load once
In that situation, we need to authorize collision on registration.
2- Inject different types and match services implementing an interface (eg: UserRepository, ProductRepository... all matching IRepository)
Collision is handled by the method responsible for invocation (eg: do.InvokeAllAs[IMyService] -> ([]IMyService, error))
b) Support Registration
Do we need to add a parameter to InjectorOpts, to define the default behavior on multiple registration? (either error or grouping or take first or take last)
If the multiplicity is supported at registration time, invocation is much simpler: do.Invoke[[]MyService](...).
c) Invocation
For implicit alias invocation, I would suggest to add do.InvokeAllAs, which creates find and loads dynamically every matching services. In that situation.
d) do.InvokeStruct
Either we have a []Repositories service registered in the container for grouping services and nothing changes:
type stuff struct {
repositories []Repository `do:`
}
Or we need to instruct do.InvokeStruct to look for all matching services:
type stuff struct {
repositories []Repository `do:",match_all"`
}
Or do.InvokeStruct search for []Repository service first and fallback on a Repository lookup if not found (seems very unsafe).
type stuff struct {
repositories []Repository `do:`
}
e) Register after invocation
Not my business. 😅
Currently, the framework authorizes only a single registration per type. Calling twice
do.ProvideValue[int](i, ...)will trigger an error. In that situation, the invocation is much simpler because we can find at most 1 service.However, starting with v2, we will support service aliasing, either via explicit declaration (
do.As[Intial, Alias](...)) or via implicit invocation (do.InvokeAs[Alias](...)), which loads the first service implementing theAliasinterface.Note: currently, a developer can override a service using
do.OverrideXXX(...). It has been suggested as a hot-service replacement in unit tests, and should be combined with.Clone()method ofRootScope. If the override is done after original service invocation, the service is replaced, but not unloaded/shutdowned.Multiple contributors asked for an improvement: #33 #75 #45 #52 #117
Poke @matdurand @svenwltr @danilobuerger @d-enk @mbark @GregPja @Jictyvoo
Checklist:
a- how to name and store the services in the DI container, while preventing collision?
b- multiple services on registration via
do.Asc- multiple services on invocation via
do.InvokeAsd- multiple services on
do.InvokeStructshadow resolutione- how to deal with post-invocation registration ?
a) Collision in container
Naming: I would suggest storing all
IServiceas a single service of type[]IService. Then, this service would be invoked withdo.Invoke[[]IService], anddo.Invoke[IService]would point to either none or the provided service.1- Inject multiple services of the same type (eg:
HttpRoute) and load onceIn that situation, we need to authorize collision on registration.
2- Inject different types and match services implementing an interface (eg:
UserRepository,ProductRepository... all matchingIRepository)Collision is handled by the method responsible for invocation (eg:
do.InvokeAllAs[IMyService] -> ([]IMyService, error))b) Support Registration
Do we need to add a parameter to
InjectorOpts, to define the default behavior on multiple registration? (either error or grouping or take first or take last)If the multiplicity is supported at registration time, invocation is much simpler:
do.Invoke[[]MyService](...).c) Invocation
For implicit alias invocation, I would suggest to add
do.InvokeAllAs, which creates find and loads dynamically every matching services. In that situation.d)
do.InvokeStructEither we have a
[]Repositoriesservice registered in the container for grouping services and nothing changes:Or we need to instruct
do.InvokeStructto look for all matching services:Or
do.InvokeStructsearch for[]Repositoryservice first and fallback on aRepositorylookup if not found (seems very unsafe).e) Register after invocation
Not my business. 😅