-
Notifications
You must be signed in to change notification settings - Fork 325
Description
Currently FX supports injecting multiple different implementations of an interface type using groups
https://pkg.go.dev/go.uber.org/fx#hdr-Value_Groups
This allows me to Provide multiple implementations of an interface Foo provided they are annotated with group, and collect them
type Params struct {
fx.In
Foos []Foo `group:"myfoos"`
where a particular Foo can be provided as
type Out struct {
fx.Out
Foo `group:"myfoos"`
However, the Foos I received back are not able to be identified by name.
Describe the solution you'd like
I would like to be able to populate a map of named foos, using the existing name annnotation:
type Params struct {
fx.In
Foos map[string]Foo `group:"myfoos"`
where a particular Foo can be provided as
type Out struct {
fx.Out
Foo1 Foo `name:"foo1" group:"myfoos"`
Foo2 Foo `name:"foo2" group:"myfoos"`
This allows me a powerful capability: To name and group a type together, and obtain it as an unordered slice, a single instance by name, or as a map of names to instances.
Describe alternatives you've considered
A trivial solution is to extend Foo to include a Name() method, and then simply organise this into a map[string]Foo.
foos := make(map[string]Foo)
for _, foo := range params.Foos {
foos[foo.Name()] = foo
}
But there are many cases where components need to be looked up by name according to dynamic configuration, that re-implementing this for each case seems inelegant and would be nice to delegate to the DI framework.
Is this a breaking change?
It is difficult to imagine a scenario where this would cause a breaking change here; but of course, there is also the curse of hindsight
- Currently attaching a group attribute to a dependency type of map fails and the application would not start, therefore this cannot be a breaking change in a practical sense.
bad argument 1: bad field "Foo" of handler.Params: value groups may be consumed as slices only: field "Foo" (map[string]string) is not a slice
- Annotating a provided dependency with both a name and a group similarly fails:
bad result 1: bad field "Foo" of handler.Result: cannot use named values with value groups: name:"foo1" provided with group:"myfoos"