-
If I have a given interface, and maybe three implementations. And I would like to use different implementation on different scenarios. Is it possible on Fx? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
Hello! Yes, you can do that with named values. When you provide each implementation, give it a name by either using // Given,
type Doer interface{ ... }
// And three implementations,
type GoodDoer struct{ ... }
func NewGoodDoer() *GoodDoer
type BadDoer struct{ ... }
func NewBadDoer() *BadDoer
type UglyDoer struct{ ... }
func NewUglyDoer() *UglyDoer
fx.Provide(
fx.Annotate(NewGoodDoer, fx.As(new(Doer)), fx.ResultTags(`name:"good"`)),
fx.Annotate(NewBadDoer, fx.As(new(Doer)), fx.ResultTags(`name:"bad"`)),
fx.Annotate(NewUglyDoer, fx.As(new(Doer)), fx.ResultTags(`name:"ugly"`)),
) If you expect to have more interfaces, you can also write a helper function: func AsDoer(f any, name string) any {
return fx.Anntoate(f, fx.As(new(Doer)), fx.ResultTags("name:" + strconv.Quote(name)))
} Then use this like so, fx.Provide(
AsDoer(NewGoodDoer, "good"),
AsDoer(NewBadDoer, "bad"),
AsDoer(NewUglyDoer, "ugly"), To consume these named values, the function that consumes them must specify the name of the desired parameter with ParamTags. func Do(good, bad, ugly Doer) {
// ...
}
fx.Invoke(
fx.Annotate(Do, fx.ParamTags(`name:"good"`, `name:"bad"`, `name:"ugly"`)),
) You can read more about this at https://pkg.go.dev/go.uber.org/fx#hdr-Named_Values and https://pkg.go.dev/go.uber.org/fx#Annotate. |
Beta Was this translation helpful? Give feedback.
Hello! Yes, you can do that with named values.
When you provide each implementation, give it a name by either using
fx.Out
, orfx.Annotate
.If your constructor returns the struct rather than the interface, you can use fx.Annotate to also adjust that.