// Copyright (c) 2021 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 digimport ()// An InvokeOption modifies the default behavior of Invoke.typeInvokeOptioninterface { applyInvokeOption(*invokeOptions)}type invokeOptions struct { Info *InvokeInfo}// InvokeInfo provides information about an Invoke.typeInvokeInfostruct { Inputs []*Input}// FillInvokeInfo is an InvokeOption that writes information on the types// accepted by the Invoke function into the specified InvokeInfo.// For example://// var info dig.InvokeInfo// err := c.Invoke(func(string, int){}, dig.FillInvokeInfo(&info))//// info.Inputs[0].String() will be string.// info.Inputs[1].String() will be int.func ( *InvokeInfo) InvokeOption {returnfillInvokeInfoOption{info: }}type fillInvokeInfoOption struct { info *InvokeInfo}func ( fillInvokeInfoOption) () string {returnfmt.Sprintf("FillInvokeInfo(%p)", .info)}func ( fillInvokeInfoOption) ( *invokeOptions) { .Info = .info}// Invoke runs the given function after instantiating its dependencies.//// Any arguments that the function has are treated as its dependencies. The// dependencies are instantiated in an unspecified order along with any// dependencies that they might have.//// The function may return an error to indicate failure. The error will be// returned to the caller as-is.//// If the [RecoverFromPanics] option was given to the container and a panic// occurs when invoking, a [PanicError] with the panic contained will be// returned. See [PanicError] for more info.func ( *Container) ( interface{}, ...InvokeOption) error {return .scope.Invoke(, ...)}// Invoke runs the given function after instantiating its dependencies.//// Any arguments that the function has are treated as its dependencies. The// dependencies are instantiated in an unspecified order along with any// dependencies that they might have.//// The function may return an error to indicate failure. The error will be// returned to the caller as-is.func ( *Scope) ( interface{}, ...InvokeOption) ( error) { := reflect.TypeOf()if == nil {returnnewErrInvalidInput("can't invoke an untyped nil", nil) }if .Kind() != reflect.Func {returnnewErrInvalidInput(fmt.Sprintf("can't invoke non-function %v (type %v)", , ), nil) } , := newParamList(, )if != nil {return }if := shallowCheckDependencies(, ); != nil {returnerrMissingDependencies{Func: digreflect.InspectFunc(),Reason: , } }if !.isVerifiedAcyclic {if , := graph.IsAcyclic(.gh); ! {returnnewErrInvalidInput("cycle detected in dependency graph", .cycleDetectedError()) } .isVerifiedAcyclic = true } , := .BuildList()if != nil {returnerrArgumentsFailed{Func: digreflect.InspectFunc(),Reason: , } }if .recoverFromPanics {deferfunc() {if := recover(); != nil { = PanicError{fn: digreflect.InspectFunc(),Panic: , } } }() }varinvokeOptionsfor , := range { .applyInvokeOption(&) }// Record info for the invoke if requestedif := .Info; != nil { := .DotParam() .Inputs = make([]*Input, len())for , := range { .Inputs[] = &Input{t: .Type,optional: .Optional,name: .Name,group: .Group, } } } := .invokerFn(reflect.ValueOf(), )iflen() == 0 {returnnil }if := [len()-1]; isError(.Type()) {if , := .Interface().(error); != nil {return } }returnnil}// Checks that all direct dependencies of the provided parameters are present in// the container. Returns an error if not.func shallowCheckDependencies( containerStore, paramList) error {varerrMissingTypes := findMissingDependencies(, .Params...)for , := range { = append(, newErrMissingTypes(, key{name: .Name, t: .Type})...) }iflen() > 0 {return }returnnil}func findMissingDependencies( containerStore, ...param) []paramSingle {var []paramSinglefor , := range {switch p := .(type) {caseparamSingle: := .getAllValueProviders(.Name, .Type) , := .getDecoratedValue(.Name, .Type)// This means that there is no provider that provides this value, // and it is NOT being decorated and is NOT optional. // In the case that there is no providers but there is a decorated value // of this type, it can be provided safely so we can safely skip this.iflen() == 0 && ! && !.Optional { = append(, ) }caseparamObject:for , := range .Fields { = append(, (, .Param)...) } } }return}
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.