Frequently Asked Questions¶
This page contains answers to common questions and issues with using Fx.
Does the order of fx.Options matter?¶
No, the order in which you provide Fx options
to fx.Options, fx.New, fx.Module, and others does not matter.
Ordering of options relative to each other is as follows:
-
Adding values: Operations like
fx.Provideandfx.Supplyare run in dependency order. Dependencies are determined by the function parameters and results.// The following are all equivalent: fx.Options(fx.Provide(ParseConfig, NewLogger)) fx.Options(fx.Provide(NewLogger, ParseConfig)) fx.Options(fx.Provide(ParseConfig), fx.Provide(NewLogger)) fx.Options(fx.Provide(NewLogger), fx.Provide(ParseConfig)) -
Consuming values: Operations like
fx.Invokeandfx.Populateare run after their dependencies have been satisfied: afterfx.Provides.Relative to each other, invokes are run in the order they were specified.
fx.Invoke(a, b) // a() is run before b()fx.Modulehierarchies affect invocation order: invocations in a parent module are run after those of a child module.fx.Options( fx.Invoke(a), fx.Module("child", fx.Invoke(b)), ), // b() is run before a() -
Replacing values: Operations like
fx.Decorateandfx.Replaceare run after the Provide operations that they depend on, but before the Invoke operations that consume those values.Ordering of decorations relative to each other is determined by
fx.Modulehierarchies: decorations in a parent module are applied after those of a child module.
Why does fx.Supply not accept interfaces?¶
This is a technical limitation of how reflection in Go works. Suppose you have:
var redisClient ClientInterface = &redis.Client{ ... }
When you call fx.Supply(redisClient),
the knowledge that you intended to use this as a ClientInterface is lost.
Fx has to use runtime reflection to inspect the type of the value,
and at that point the Go runtime only tells it that it’s a *redis.Client.
You can work around this with the fx.Annotate function
and the fx.As annotation.
fx.Supply(
fx.Annotate(redisClient, fx.As(new(ClientInterface))),
)