Package Usage: go: go.uber.org/fx
Package fx is a framework that makes it easy to build applications out of
reusable, composable modules.
Fx applications use dependency injection to eliminate globals without the
tedium of manually wiring together function calls. Unlike other approaches
to dependency injection, Fx works with plain Go functions: you don't need
to use struct tags or embed special types, so Fx automatically works well
with most Go packages.
Basic usage is explained in the package-level example.
If you're new to Fx, start there!
Advanced features, including named instances, optional parameters,
and value groups, are explained in this section further down.
To test functions that use the Lifecycle type or to write end-to-end tests
of your Fx application, use the helper functions and types provided by the
go.uber.org/fx/fxtest package.
Fx constructors declare their dependencies as function parameters. This can
quickly become unreadable if the constructor has a lot of dependencies.
To improve the readability of constructors like this, create a struct that
lists all the dependencies as fields and change the function to accept that
struct instead. The new struct is called a parameter struct.
Fx has first class support for parameter structs: any struct embedding
fx.In gets treated as a parameter struct, so the individual fields in the
struct are supplied via dependency injection. Using a parameter struct, we
can make the constructor above much more readable:
Though it's rarelly necessary to mix the two, constructors can receive any
combination of parameter structs and parameters.
Result structs are the inverse of parameter structs.
These structs represent multiple outputs from a
single function as fields. Fx treats all structs embedding fx.Out as result
structs, so other constructors can rely on the result struct's fields
directly.
Without result structs, we sometimes have function definitions like this:
With result structs, we can make this both more readable and easier to
modify in the future:
Some use cases require the application container to hold multiple values of
the same type.
A constructor that produces a result struct can tag any field with
`name:".."` to have the corresponding value added to the graph under the
specified name. An application may contain at most one unnamed value of a
given type, but may contain any number of named values of the same type.
Similarly, a constructor that accepts a parameter struct can tag any field
with `name:".."` to have the corresponding value injected by name.
Note that both the name AND type of the fields on the
parameter struct must match the corresponding result struct.
Constructors often have optional dependencies on some types: if those types are
missing, they can operate in a degraded state. Fx supports optional
dependencies via the `optional:"true"` tag to fields on parameter structs.
If an optional field isn't available in the container, the constructor
receives the field's zero value.
Constructors that declare optional dependencies MUST gracefully handle
situations in which those dependencies are absent.
The optional tag also allows adding new dependencies without breaking
existing consumers of the constructor.
The optional tag may be combined with the name tag to declare a named
value dependency optional.
To make it easier to produce and consume many values of the same type, Fx
supports named, unordered collections called value groups.
Constructors can send values into value groups by returning a result struct
tagged with `group:".."`.
Any number of constructors may provide values to this named collection, but
the ordering of the final collection is unspecified.
Value groups require parameter and result structs to use fields with
different types: if a group of constructors each returns type T, parameter
structs consuming the group must use a field of type []T.
Parameter structs can request a value group by using a field of type []T
tagged with `group:".."`.
This will execute all constructors that provide a value to
that group in an unspecified order, then collect all the results into a
single slice.
Note that values in a value group are unordered. Fx makes no guarantees
about the order in which these values will be produced.
By default, when a constructor declares a dependency on a value group,
all values provided to that value group are eagerly instantiated.
That is undesirable for cases where an optional component wants to
constribute to a value group, but only if it was actually used
by the rest of the application.
A soft value group can be thought of as a best-attempt at populating the
group with values from constructors that have already run. In other words,
if a constructor's output type is only consumed by a soft value group,
it will not be run.
Note that Fx randomizes the order of values in the value group,
so the slice of values may not match the order in which constructors
were run.
To declare a soft relationship between a group and its constructors, use
the `soft` option on the input group tag (`group:"[groupname],soft"`).
This option is only valid for input parameters.
With such a declaration, a constructor that provides a value to the 'server'
value group will be called only if there's another instantiated component
that consumes the results of that constructor.
NewHandlerAndLogger will be called because the Logger is consumed by the
application, but NewHandler will not be called because it's only consumed
by the soft value group.
By default, values of type T produced to a value group are consumed as []T.
This means that if the producer produces []T,
the consumer must consume [][]T.
There are cases where it's desirable
for the producer (the fx.Out) to produce multiple values ([]T),
and for the consumer (the fx.In) consume them as a single slice ([]T).
Fx offers flattened value groups for this purpose.
To provide multiple values for a group from a result struct, produce a
slice and use the `,flatten` option on the group tag. This indicates that
each element in the slice should be injected into the group individually.
By default, a type that embeds fx.In may not have any unexported fields. The
following will return an error if used with Fx.
If you have need of unexported fields on such a type, you may opt-into
ignoring unexported fields by adding the ignore-unexported struct tag to the
fx.In. For example,
45 versions
Latest release: about 1 year ago
2,015 dependent packages
View more package details: https://packages.ecosystem.code.gouv.fr/registries/proxy.golang.org/packages/go.uber.org/fx