// Copyright (c) 2022 Uber Technologies, Inc.//// Permission is hereby granted, free of charge, to any person obtaining a copy// of this software and associated documentation files (the "Software"), to deal// in the Software without restriction, including without limitation the rights// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell// copies of the Software, and to permit persons to whom the Software is// furnished to do so, subject to the following conditions://// The above copyright notice and this permission notice shall be included in// all copies or substantial portions of the Software.//// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN// THE SOFTWARE.package fximport ()// Provide registers any number of constructor functions, teaching the// application how to instantiate various types. The supplied constructor// function(s) may depend on other types available in the application, must// return one or more objects, and may return an error. For example://// // Constructs type *C, depends on *A and *B.// func(*A, *B) *C//// // Constructs type *C, depends on *A and *B, and indicates failure by// // returning an error.// func(*A, *B) (*C, error)//// // Constructs types *B and *C, depends on *A, and can fail.// func(*A) (*B, *C, error)//// The order in which constructors are provided doesn't matter, and passing// multiple Provide options appends to the application's collection of// constructors. Constructors are called only if one or more of their returned// types are needed, and their results are cached for reuse (so instances of a// type are effectively singletons within an application). Taken together,// these properties make it perfectly reasonable to Provide a large number of// constructors even if only a fraction of them are used.//// See the documentation of the In and Out types for advanced features,// including optional parameters and named instances.//// See the documentation for [Private] for restricting access to constructors.//// Constructor functions should perform as little external interaction as// possible, and should avoid spawning goroutines. Things like server listen// loops, background timer loops, and background processing goroutines should// instead be managed using Lifecycle callbacks.func ( ...interface{}) Option {returnprovideOption{Targets: ,Stack: fxreflect.CallerStack(1, 0), }}type provideOption struct { Targets []interface{} Stack fxreflect.Stack}func ( provideOption) ( *module) {varbool := make([]interface{}, 0, len(.Targets))for , := range .Targets {if , := .(privateOption); { = truecontinue } = append(, ) }for , := range { .provides = append(.provides, provide{Target: ,Stack: .Stack,Private: , }) }}type privateOption struct{}// Private is an option that can be passed as an argument to [Provide] or [Supply] to// restrict access to the constructors being provided. Specifically,// corresponding constructors can only be used within the current module// or modules the current module contains. Other modules that contain this// module won't be able to use the constructor.//// For example, the following would fail because the app doesn't have access// to the inner module's constructor.//// fx.New(// fx.Module("SubModule", fx.Provide(func() int { return 0 }, fx.Private)),// fx.Invoke(func(a int) {}),// )varPrivate = privateOption{}func ( provideOption) () string { := make([]string, len(.Targets))for , := range .Targets { [] = fxreflect.FuncName() }returnfmt.Sprintf("fx.Provide(%s)", strings.Join(, ", "))}func runProvide( container, provide, ...dig.ProvideOption) error { := .Targetif , := .(Option); {returnfmt.Errorf("fx.Option should be passed to fx.New directly, "+"not to fx.Provide: fx.Provide received %v from:\n%+v", , .Stack) }switch constructor := .(type) {caseannotationError:// fx.Annotate failed. Turn it into an Fx error.returnfmt.Errorf("encountered error while applying annotation using fx.Annotate to %s: %w",fxreflect.FuncName(.target), .err)caseannotated: , := .Build()if != nil {returnfmt.Errorf("fx.Provide(%v) from:\n%+vFailed: %w", , .Stack, ) } = append(, dig.LocationForPC(.FuncPtr))if := .Provide(, ...); != nil {returnfmt.Errorf("fx.Provide(%v) from:\n%+vFailed: %w", , .Stack, ) }caseAnnotated: := switch {caselen(.Group) > 0 && len(.Name) > 0:returnfmt.Errorf("fx.Annotated may specify only one of Name or Group: received %v from:\n%+v", , .Stack)caselen(.Name) > 0: = append(, dig.Name(.Name))caselen(.Group) > 0: = append(, dig.Group(.Group)) }if := .Provide(.Target, ...); != nil {returnfmt.Errorf("fx.Provide(%v) from:\n%+vFailed: %w", , .Stack, ) }default:ifreflect.TypeOf().Kind() == reflect.Func { := reflect.ValueOf().Type()for := 0; < .NumOut(); ++ { := .Out()if == reflect.TypeOf(Annotated{}) {returnfmt.Errorf("fx.Annotated should be passed to fx.Provide directly, "+"it should not be returned by the constructor: "+"fx.Provide received %v from:\n%+v",fxreflect.FuncName(), .Stack) } } }if := .Provide(, ...); != nil {returnfmt.Errorf("fx.Provide(%v) from:\n%+vFailed: %w", fxreflect.FuncName(), .Stack, ) } }returnnil}
The pages are generated with Goldsv0.8.2. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.