Sitelet https://github.com/samber/do/issues/114
Skip to content

Multiple registration and bulk invocation #114

Description

@samber

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. 😅

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions