Source File
replace.go
Belonging Package
go.uber.org/fx
// 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 ()// Replace provides instantiated values for graph modification as if// they had been provided using a decorator with fx.Decorate.// The most specific type of each value (as determined by reflection) is used.//// Refer to the documentation on fx.Decorate to see how graph modifications// work with fx.Module.//// This serves a purpose similar to what fx.Supply does for fx.Provide.//// For example, given,//// var log *zap.Logger = ...//// The following two forms are equivalent.//// fx.Replace(log)//// fx.Decorate(// func() *zap.Logger {// return log// },// )//// Replace panics if a value (or annotation target) is an untyped nil or an error.//// # Replace Caveats//// As mentioned above, Replace uses the most specific type of the provided// value. For interface values, this refers to the type of the implementation,// not the interface. So if you try to replace an io.Writer, fx.Replace will// use the type of the implementation.//// var stderr io.Writer = os.Stderr// fx.Replace(stderr)//// Is equivalent to,//// fx.Decorate(func() *os.File { return os.Stderr })//// This is typically NOT what you intended. To replace the io.Writer in the// container with the value above, we need to use the fx.Annotate function with// the fx.As annotation.//// fx.Replace(// fx.Annotate(os.Stderr, fx.As(new(io.Writer)))// )func ( ...interface{}) Option {:= make([]interface{}, len()) // one function per value:= make([]reflect.Type, len())for , := range {switch value := .(type) {case annotated:var reflect.Type.Target, = newReplaceDecorator(.Target)[] =[] =default:[], [] = newReplaceDecorator()}}return replaceOption{Targets: ,Types: ,Stack: fxreflect.CallerStack(1, 0),}}type replaceOption struct {Targets []interface{}Types []reflect.Type // type of value produced by constructor[i]Stack fxreflect.Stack}func ( replaceOption) ( *module) {for , := range .Targets {.decorators = append(.decorators, decorator{Target: ,Stack: .Stack,IsReplace: true,ReplaceType: .Types[],})}}func ( replaceOption) () string {:= make([]string, 0, len(.Targets))for , := range .Types {= append(, .String())}return fmt.Sprintf("fx.Replace(%s)", strings.Join(, ", "))}// Returns a function that takes no parameters, and returns the given value.func newReplaceDecorator( interface{}) (interface{}, reflect.Type) {switch .(type) {case nil:panic("untyped nil passed to fx.Replace")case error:panic("error value passed to fx.Replace")}:= reflect.TypeOf():= []reflect.Type{}:= []reflect.Value{reflect.ValueOf()}:= reflect.FuncOf([]reflect.Type{}, , false):= reflect.MakeFunc(, func([]reflect.Value) []reflect.Value {return})return .Interface(),}
![]() |
The pages are generated with Golds v0.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. |