| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 | package diimport (	"fmt"	"strings"	"kpt-tmr-group/pkg/di/xreflect"	"go.uber.org/dig")// Option configures a Hub. It's included for future functionality;// currently, there are no concrete implementations.type Option = dig.Option// A ProvideOption modifies the default behavior of Provide.type ProvideOption = dig.ProvideOption// An InvokeOption modifies the default behavior of Invoke. It's included for// future functionality; currently, there are no concrete implementations.type InvokeOption = dig.InvokeOption// HubOption is an option configures an Hub using the functional options paradigm// popularized by Rob Pike. If you're unfamiliar with this style, see// https://commandcenter.blogspot.com/2014/01/self-referential-functions-and-design.html.type HubOption interface {	fmt.Stringer	Apply(hub *Hub)}// Options converts a collection of Options into a single Option. This allows// packages to bundle sophisticated functionality into easy-to-use Fx modules.// For example, a logging package might export a simple option like this:////  package logging////  var Module = fx.Provide(func() *log.Logger {//    return log.New(os.Stdout, "", 0)//  })//// A shared all-in-one microservice package could then use Options to bundle// logging with similar metrics, tracing, and gRPC modules:////  package server////  var Module = fx.Options(//    logging.Module,//    metrics.Module,//    tracing.Module,//    grpc.Module,//  )//// Since this all-in-one module1 has a minimal API surface, it's easy to add// new functionality to it without breaking existing users. Individual// applications can take advantage of all this functionality with only one// line of code:////  app := di.New(server.Module)//// Use this pattern sparingly, since it limits the user's ability to customize// their application.func Options(opts ...HubOption) HubOption {	return optionGroup(opts)}type optionGroup []HubOptionfunc (og optionGroup) Apply(hub *Hub) {	for _, opt := range og {		opt.Apply(hub)	}}func (og optionGroup) String() string {	items := make([]string, len(og))	for i, opt := range og {		items[i] = fmt.Sprint(opt)	}	return fmt.Sprintf("di.Options(%s)", strings.Join(items, ", "))}// Annotation define annotated and apply to Provided// Annotation provides instantiated values for dependency injection as if// they had been provided using a constructor that simply returns them.// The most specific type of each value (as determined by reflection) is used.////	type K0 struct {//		Closed bool//	}////	func (k *K0) Close() {//		k.Closed = true//	}////	k0 := &K0{}//	var module = Annotation(func(ann *Annotated) {//		ann.Target = func() *K0 { return k0 }//		ann.Close = k0.Close//	})////	hub, err := di.New(module)func Annotation(f func(ann *Annotated)) HubOption {	annotation := &Annotated{}	f(annotation)	return provideOption{		Targets: []interface{}{*annotation},		Stack:   xreflect.CallerStack(1, 0),	}}// 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)func Provide(constructors ...interface{}) HubOption {	// check no nil or error	for _, value := range constructors {		switch value.(type) {		case nil:			panic("untyped nil passed to di.Provide")		case error:			panic("error value passed to di.Provide")		}	}	return provideOption{		Targets: constructors,		Stack:   xreflect.CallerStack(1, 0),	}}type provideOption struct {	Targets []interface{}	Stack   xreflect.Stack}func (o provideOption) Apply(hub *Hub) {	for _, target := range o.Targets {		hub.provides = append(hub.provides, Provided{			Target: target,			Stack:  o.Stack,		})	}}func (o provideOption) String() string {	items := make([]string, len(o.Targets))	for i, c := range o.Targets {		items[i] = xreflect.FuncName(c)	}	return fmt.Sprintf("fx.Provide(%s)", strings.Join(items, ", "))}// ValidateHub validates that supplied graph would run and is not missing any dependencies.func ValidateHub(v bool) HubOption {	return validateOption{validate: v}}type validateOption struct {	validate bool}func (o validateOption) Apply(hub *Hub) {	hub.validate = o.validate}func (o validateOption) String() string {	return fmt.Sprintf("fx.validate(%v)", o.validate)}
 |