// 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 ()const ( _optionalTag = "optional" _nameTag = "name" _ignoreUnexportedTag = "ignore-unexported")// Unique identification of an object in the graph.type key struct { t reflect.Type// Only one of name or group will be set. name string group string}func ( key) () string {if .name != "" {returnfmt.Sprintf("%v[name=%q]", .t, .name) }if .group != "" {returnfmt.Sprintf("%v[group=%q]", .t, .group) }return .t.String()}// Option configures a Container.typeOptioninterface { applyOption(*Container)}// Container is a directed acyclic graph of types and their dependencies.// A Container is the root Scope that represents the top-level scoped// directed acyclic graph of the dependencies.typeContainerstruct {// this is the "root" Scope that represents the // root of the scope tree. scope *Scope}// containerWriter provides write access to the Container's underlying data// store.type containerWriter interface {// setValue sets the value with the given name and type in the container. // If a value with the same name and type already exists, it will be // overwritten. setValue(name string, t reflect.Type, v reflect.Value)// setDecoratedValue sets a decorated value with the given name and type // in the container. If a decorated value with the same name and type already // exists, it will be overwritten. setDecoratedValue(name string, t reflect.Type, v reflect.Value)// submitGroupedValue submits a value to the value group with the provided // name. submitGroupedValue(name string, t reflect.Type, v reflect.Value)// submitDecoratedGroupedValue submits a decorated value to the value group // with the provided name. submitDecoratedGroupedValue(name string, t reflect.Type, v reflect.Value)}// containerStore provides access to the Container's underlying data store.type containerStore interface {containerWriter// Adds a new graph node to the Container newGraphNode(w interface{}, orders map[*Scope]int)// Returns a slice containing all known types. knownTypes() []reflect.Type// Retrieves the value with the provided name and type, if any. getValue(name string, t reflect.Type) (v reflect.Value, ok bool)// Retrieves a decorated value with the provided name and type, if any. getDecoratedValue(name string, t reflect.Type) (v reflect.Value, ok bool)// Retrieves all values for the provided group and type. // // The order in which the values are returned is undefined. getValueGroup(name string, t reflect.Type) []reflect.Value// Retrieves all decorated values for the provided group and type, if any. getDecoratedValueGroup(name string, t reflect.Type) (reflect.Value, bool)// Returns the providers that can produce a value with the given name and // type. getValueProviders(name string, t reflect.Type) []provider// Returns the providers that can produce values for the given group and // type. getGroupProviders(name string, t reflect.Type) []provider// Returns the providers that can produce a value with the given name and // type across all the Scopes that are in effect of this containerStore. getAllValueProviders(name string, t reflect.Type) []provider// Returns the decorator that can decorate values for the given name and // type. getValueDecorator(name string, t reflect.Type) (decorator, bool)// Reutrns the decorator that can decorate values for the given group and // type. getGroupDecorator(name string, t reflect.Type) (decorator, bool)// Reports a list of stores (starting at this store) up to the root // store. storesToRoot() []containerStore createGraph() *dot.Graph// Returns invokerFn function to use when calling arguments. invoker() invokerFn// Returns a clock to use clock() digclock.Clock}// New constructs a Container.func ( ...Option) *Container { := newScope() := &Container{scope: }for , := range { .applyOption() }return}// DeferAcyclicVerification is an Option to override the default behavior// of container.Provide, deferring the dependency graph validation to no longer// run after each call to container.Provide. The container will instead verify// the graph on first `Invoke`.//// Applications adding providers to a container in a tight loop may experience// performance improvements by initializing the container with this option.func () Option {returndeferAcyclicVerificationOption{}}type deferAcyclicVerificationOption struct{}func (deferAcyclicVerificationOption) () string {return"DeferAcyclicVerification()"}func (deferAcyclicVerificationOption) ( *Container) { .scope.deferAcyclicVerification = true}// RecoverFromPanics is an [Option] to recover from panics that occur while// running functions given to the container. When set, recovered panics// will be placed into a [PanicError], and returned at the invoke callsite.// See [PanicError] for an example on how to handle panics with this option// enabled, and distinguish them from errors.func () Option {returnrecoverFromPanicsOption{}}type recoverFromPanicsOption struct{}func (recoverFromPanicsOption) () string {return"RecoverFromPanics()"}func (recoverFromPanicsOption) ( *Container) { .scope.recoverFromPanics = true}// Changes the source of randomness for the container.//// This will help provide determinism during tests.func setRand( *rand.Rand) Option {returnsetRandOption{r: }}type setRandOption struct{ r *rand.Rand }func ( setRandOption) () string {returnfmt.Sprintf("setRand(%p)", .r)}func ( setRandOption) ( *Container) { .scope.rand = .r}// Changes the source of time for the container.func setClock( digclock.Clock) Option {returnsetClockOption{c: }}type setClockOption struct{ c digclock.Clock }func ( setClockOption) () string {returnfmt.Sprintf("setClock(%v)", .c)}func ( setClockOption) ( *Container) { .scope.clockSrc = .c}// DryRun is an Option which, when set to true, disables invocation of functions supplied to// Provide and Invoke. Use this to build no-op containers.func ( bool) Option {returndryRunOption()}type dryRunOption boolfunc ( dryRunOption) () string {returnfmt.Sprintf("DryRun(%v)", bool())}func ( dryRunOption) ( *Container) {if { .scope.invokerFn = dryInvoker } else { .scope.invokerFn = defaultInvoker }}// invokerFn specifies how the container calls user-supplied functions.type invokerFn func(fn reflect.Value, args []reflect.Value) (results []reflect.Value)func defaultInvoker( reflect.Value, []reflect.Value) []reflect.Value {return .Call()}// Generates zero values for results without calling the supplied function.func dryInvoker( reflect.Value, []reflect.Value) []reflect.Value { := .Type() := make([]reflect.Value, .NumOut())for := 0; < .NumOut(); ++ { [] = reflect.Zero(.Type().Out()) }return}// String representation of the entire Containerfunc ( *Container) () string {return .scope.String()}// Scope creates a child scope of the Container with the given name.func ( *Container) ( string, ...ScopeOption) *Scope {return .scope.Scope(, ...)}type byTypeName []reflect.Typefunc ( byTypeName) () int {returnlen()}func ( byTypeName) ( int, int) bool {returnfmt.Sprint([]) < fmt.Sprint([])}func ( byTypeName) ( int, int) { [], [] = [], []}func shuffledCopy( *rand.Rand, []reflect.Value) []reflect.Value { := make([]reflect.Value, len())for , := range .Perm(len()) { [] = [] }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.