github.com/sohaha/zlsgo@v1.7.13-0.20240501141223-10dd1a906f76/zdi/di.go (about)

     1  package zdi
     2  
     3  import (
     4  	"reflect"
     5  )
     6  
     7  type (
     8  	Injector interface {
     9  		Invoker
    10  		TypeMapper
    11  		Set(reflect.Type, reflect.Value)
    12  		Get(reflect.Type) (reflect.Value, bool)
    13  		SetParent(Injector)
    14  	}
    15  	Invoker interface {
    16  		Apply(Pointer) error
    17  		Resolve(...Pointer) error
    18  		Invoke(interface{}) ([]reflect.Value, error)
    19  		InvokeWithErrorOnly(interface{}) error
    20  	}
    21  	TypeMapper interface {
    22  		Map(interface{}, ...Option) reflect.Type
    23  		Maps(...interface{}) []reflect.Type
    24  		Provide(interface{}, ...Option) []reflect.Type
    25  	}
    26  )
    27  
    28  type (
    29  	Pointer   interface{}
    30  	Option    func(*mapOption)
    31  	mapOption struct {
    32  		key reflect.Type
    33  	}
    34  	injector struct {
    35  		values    map[reflect.Type]reflect.Value
    36  		providers map[reflect.Type]reflect.Value
    37  		parent    Injector
    38  	}
    39  )
    40  
    41  func New(parent ...Injector) Injector {
    42  	inj := &injector{
    43  		values:    make(map[reflect.Type]reflect.Value),
    44  		providers: make(map[reflect.Type]reflect.Value),
    45  	}
    46  	if len(parent) > 0 {
    47  		inj.parent = parent[0]
    48  	}
    49  	return inj
    50  }
    51  
    52  func (inj *injector) SetParent(parent Injector) {
    53  	inj.parent = parent
    54  }
    55  
    56  func WithInterface(ifacePtr Pointer) Option {
    57  	return func(opt *mapOption) {
    58  		opt.key = ifeOf(ifacePtr)
    59  	}
    60  }
    61  
    62  func ifeOf(value interface{}) reflect.Type {
    63  	t := reflect.TypeOf(value)
    64  	for t.Kind() == reflect.Ptr {
    65  		t = t.Elem()
    66  	}
    67  
    68  	if t.Kind() != reflect.Interface {
    69  		panic("called inject.key with a value that is not a pointer to an interface. (*MyInterface)(nil)")
    70  	}
    71  	return t
    72  }