gitee.com/lh-her-team/common@v1.5.1/container/container.go (about)

     1  package container
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"reflect"
     7  	"strings"
     8  	"unsafe"
     9  )
    10  
    11  var (
    12  	errNotFound = errors.New("not found")
    13  )
    14  
    15  type binding struct {
    16  	specifiedParameters map[int]interface{} //构造对象时参数指定的值
    17  	dependsOn           map[int]string      //构造对象时依赖的其他对象的name
    18  	constructor         interface{}         //构造函数指针,用于构造对应的实例
    19  	instance            interface{}         //在默认单例情况下,存储对应的绑定的实例
    20  	isTransient         bool                //是否是临时对象
    21  	isDefault           bool                //是否是默认对象
    22  	name                string              //对应的名字
    23  	resolveTypes        []reflect.Type      //指定构造函数返回的参数列表对应的接口类型,如果不指定某个返回值,可以设置为nil
    24  	optionalIndexes     map[int]bool        //哪些参数是可选的,如果可选,那么即使无法找到对应实例也不会报错
    25  }
    26  
    27  func (b *binding) Clone() *binding {
    28  	clone := &binding{
    29  		specifiedParameters: make(map[int]interface{}, len(b.specifiedParameters)),
    30  		dependsOn:           make(map[int]string, len(b.dependsOn)),
    31  		constructor:         b.constructor,
    32  		instance:            b.instance,
    33  		isTransient:         b.isTransient,
    34  		isDefault:           b.isDefault,
    35  		name:                b.name,
    36  		resolveTypes:        b.resolveTypes,
    37  		optionalIndexes:     make(map[int]bool, len(b.optionalIndexes)),
    38  	}
    39  	for k, v := range b.specifiedParameters {
    40  		clone.specifiedParameters[k] = v
    41  	}
    42  	for k, v := range b.dependsOn {
    43  		clone.dependsOn[k] = v
    44  	}
    45  	for k, v := range b.optionalIndexes {
    46  		clone.optionalIndexes[k] = v
    47  	}
    48  	return clone
    49  }
    50  
    51  // resolve creates an appropriate implementation of the related abstraction
    52  func (b *binding) resolve(c *Container) (interface{}, error) {
    53  	if b.instance != nil {
    54  		return b.instance, nil
    55  	}
    56  	instList, err := c.invoke(b.constructor, b.specifiedParameters, b.dependsOn, b.optionalIndexes)
    57  	if err != nil {
    58  		return nil, err
    59  	}
    60  	if len(instList) == 0 {
    61  		return nil, errors.New("resolve function must return instance")
    62  	}
    63  	inst := instList[0]
    64  	if !b.isTransient {
    65  		b.instance = inst
    66  	}
    67  	return inst, err
    68  }
    69  
    70  type namedBinding struct {
    71  	defaultBinding *binding
    72  	namedBinding   map[string]*binding
    73  }
    74  
    75  func (nb *namedBinding) Clone() *namedBinding {
    76  	clone := &namedBinding{
    77  		defaultBinding: nb.defaultBinding.Clone(),
    78  		namedBinding:   make(map[string]*binding, len(nb.namedBinding)),
    79  	}
    80  	for k, v := range nb.namedBinding {
    81  		clone.namedBinding[k] = v.Clone()
    82  	}
    83  	return clone
    84  }
    85  
    86  func newNamedBinding(b *binding) *namedBinding {
    87  	bindings := make(map[string]*binding)
    88  	bindings[b.name] = b
    89  	return &namedBinding{defaultBinding: b, namedBinding: bindings}
    90  }
    91  
    92  func (nb *namedBinding) addNewBinding(b *binding, isDefault bool) {
    93  	if isDefault {
    94  		nb.defaultBinding = b
    95  	}
    96  	nb.namedBinding[b.name] = b
    97  }
    98  
    99  // Container interface类型->map["name"]binding对象,如果没有命名实例,那么name就是""
   100  type Container struct {
   101  	bind  map[reflect.Type]*namedBinding
   102  	alias map[reflect.Type]reflect.Type
   103  }
   104  
   105  // NewContainer creates a new instance of the Container
   106  func NewContainer() *Container {
   107  	return &Container{
   108  		bind:  make(map[reflect.Type]*namedBinding),
   109  		alias: make(map[reflect.Type]reflect.Type),
   110  	}
   111  }
   112  
   113  //Register 注册一个对象的构造函数到容器中,该构造函数接收其他interface对象或者值对象作为参数,返回interface对象
   114  //注意返回的应该是interface,而不应该是具体的struct类型的指针
   115  func (c *Container) Register(constructor interface{}, options ...Option) error {
   116  	//检查resolver必须是一个构造函数
   117  	reflectedResolver := reflect.TypeOf(constructor)
   118  	if reflectedResolver.Kind() != reflect.Func {
   119  		return errors.New("container: the constructor must be a function")
   120  	}
   121  	//遍历构造函数的输出,找到具体构造的类型,并将这些类型放入到container中
   122  	for i := 0; i < reflectedResolver.NumOut(); i++ {
   123  		//构造新的binding对象
   124  		b := &binding{constructor: constructor, specifiedParameters: make(map[int]interface{})}
   125  		for _, op := range options {
   126  			err := op(b)
   127  			if err != nil {
   128  				return err
   129  			}
   130  		}
   131  		resolveType := reflectedResolver.Out(i)
   132  		if len(b.resolveTypes) > i && b.resolveTypes[i] != nil { //如果指定了映射的interface,则使用指定的
   133  			if !resolveType.Implements(b.resolveTypes[i]) {
   134  				return errors.New("resolve type " + resolveType.String() + " not implement " + b.resolveTypes[i].String())
   135  			}
   136  			resolveType = b.resolveTypes[i]
   137  		}
   138  		if namedBinding, has := c.bind[resolveType]; has { //增加新binding
   139  			namedBinding.addNewBinding(b, b.isDefault)
   140  		} else { //没有注册过这个接口的任何绑定
   141  			c.bind[resolveType] = newNamedBinding(b)
   142  		}
   143  	}
   144  	return nil
   145  }
   146  
   147  //RegisterInstance 注册一个对象的实例到容器中
   148  //参数interfacePtr 是一个接口的指针
   149  //参数instance 是实例值
   150  func (c *Container) RegisterInstance(interfacePtr interface{}, instance interface{}, options ...Option) error {
   151  	b := &binding{instance: instance}
   152  	for _, op := range options {
   153  		err := op(b)
   154  		if err != nil {
   155  			return err
   156  		}
   157  	}
   158  	t, err := getTypeFromInterface(interfacePtr)
   159  	if err != nil {
   160  		return err
   161  	}
   162  	if namedBinding, has := c.bind[t]; has { //增加新的绑定
   163  		namedBinding.addNewBinding(b, b.isDefault)
   164  	} else { //没有注册过这个接口的任何绑定
   165  		c.bind[t] = newNamedBinding(b)
   166  	}
   167  	return nil
   168  }
   169  
   170  //RegisterSubInterface 注册一个子接口到某个接口
   171  func (c *Container) RegisterSubInterface(subInterfacePtr interface{}, interfacePtr interface{}) error {
   172  	stype, err := getTypeFromInterface(subInterfacePtr)
   173  	if err != nil {
   174  		return err
   175  	}
   176  	itype, err := getTypeFromInterface(interfacePtr)
   177  	if err != nil {
   178  		return err
   179  	}
   180  	c.alias[stype] = itype
   181  	return nil
   182  }
   183  
   184  func (c *Container) SetDefaultBinding(interfacePtr interface{}, defaultName string) error {
   185  	itype, err := getTypeFromInterface(interfacePtr)
   186  	if err != nil {
   187  		return err
   188  	}
   189  	if nameBinding, ok := c.bind[itype]; ok {
   190  		if theBinding, found := nameBinding.namedBinding[defaultName]; found {
   191  			nameBinding.defaultBinding = theBinding
   192  			return nil
   193  		}
   194  	}
   195  	return errNotFound
   196  }
   197  
   198  func getTypeFromInterface(interfacePtr interface{}) (reflect.Type, error) {
   199  	ptr := reflect.TypeOf(interfacePtr)
   200  	if ptr == nil || ptr.Kind() != reflect.Ptr {
   201  		return nil, errors.New("interfacePtr must be a interface point, not a interface value")
   202  	}
   203  	return ptr.Elem(), nil
   204  }
   205  
   206  // arguments 通过容器获得一个函数的传入参数的值列表
   207  func (c *Container) arguments(function interface{}, specifiedParameters map[int]interface{},
   208  	dependsOn map[int]string, optionalIndexes map[int]bool) ([]reflect.Value, error) {
   209  	reflectedFunction := reflect.TypeOf(function)
   210  	argumentsCount := reflectedFunction.NumIn()
   211  	arguments := make([]reflect.Value, argumentsCount)
   212  	for i := 0; i < argumentsCount; i++ {
   213  		abstraction := reflectedFunction.In(i)
   214  		if specifiedValue, has := specifiedParameters[i]; has { //如果是指定了参数的,直接获得参数值
   215  			if isNil(specifiedValue) { //如果在指定参数中设置了nil,那么表示强制将该值设为空,
   216  				arguments[i] = reflect.Zero(abstraction)
   217  				continue
   218  			}
   219  			//如果参数是struct类型,需要调用Fill填充这个struct中的字段
   220  			fieldKind := reflect.TypeOf(specifiedValue).Kind()
   221  			if fieldKind == reflect.Struct {
   222  				err := c.Fill(&specifiedValue)
   223  				if err != nil {
   224  					return nil, err
   225  				}
   226  			}
   227  			if fieldKind == reflect.Ptr { //如果是指针,那么获得对应的值类型,判断是否struct,是则Fill
   228  				elem := reflect.TypeOf(specifiedValue).Elem()
   229  				if elem.Kind() == reflect.Struct {
   230  					err := c.Fill(specifiedValue)
   231  					if err != nil {
   232  						return nil, err
   233  					}
   234  				}
   235  			}
   236  			arguments[i] = reflect.ValueOf(specifiedValue)
   237  			continue
   238  		}
   239  		name := dependsOn[i]
   240  		b, err := c.getBinding(abstraction, name)
   241  		if err != nil {
   242  			//找不到该函数对应的参数类型的映射,如果是optional的,则设为空,否则报错
   243  			if _, optional := optionalIndexes[i]; optional {
   244  				arguments[i] = reflect.Zero(abstraction)
   245  				continue
   246  			}
   247  			//必填字段找不到,报错
   248  			resolveType := ""
   249  			o := reflectedFunction.Out(0)
   250  			if o != nil {
   251  				resolveType = o.String()
   252  			}
   253  			return nil, errors.New("resolve type: " + resolveType + " no concrete found for: " + abstraction.String())
   254  		}
   255  		instance, err := b.resolve(c)
   256  		if err != nil {
   257  			return nil, err
   258  		}
   259  		arguments[i] = reflect.ValueOf(instance)
   260  	}
   261  	return arguments, nil
   262  }
   263  
   264  func (c *Container) getBinding(theType reflect.Type, name string) (*binding, error) {
   265  	if namedBinding, exist := c.bind[theType]; exist {
   266  		//从容器中找到了对应的binding
   267  		//如果使用DependsOn指定了依赖的对象的name,那么通过指定的name获取binding
   268  		if name != "" {
   269  			if b, ok := namedBinding.namedBinding[name]; ok {
   270  				return b, nil
   271  			}
   272  			return nil, errors.New("container: no concrete found for: " + theType.String() + " name: " + name)
   273  
   274  		}
   275  		//没有通过name指定,那么就取默认的binding
   276  		return namedBinding.defaultBinding, nil
   277  	}
   278  	//找不到该函数对应的参数类型的映射,在alias中找
   279  	if aType, ok := c.alias[theType]; ok {
   280  		return c.getBinding(aType, name)
   281  	}
   282  	return nil, errNotFound
   283  }
   284  
   285  func (c *Container) invoke(function interface{}, specifiedParameters map[int]interface{},
   286  	dependsOn map[int]string, optionalIndexes map[int]bool) (
   287  	[]interface{}, error) {
   288  	args, err := c.arguments(function, specifiedParameters, dependsOn, optionalIndexes)
   289  	if err != nil {
   290  		return nil, err
   291  	}
   292  	returns := reflect.ValueOf(function).Call(args)
   293  	if len(returns) == 0 {
   294  		return nil, nil
   295  	}
   296  	returnList := []interface{}{}
   297  	var errPtr *error
   298  	errType := reflect.TypeOf(errPtr).Elem()
   299  	for _, rt := range returns {
   300  		if !rt.IsNil() && rt.Type().Implements(errType) { //返回类型中有不为空的error
   301  			return nil, rt.Interface().(error)
   302  		}
   303  		returnList = append(returnList, rt.Interface())
   304  	}
   305  	return returnList, nil
   306  }
   307  
   308  //Resolve input interface, resolve instance. 传入接口的指针,获得对应的实例
   309  func (c *Container) Resolve(abstraction interface{}, options ...ResolveOption) error {
   310  	receiverType := reflect.TypeOf(abstraction)
   311  	if receiverType == nil {
   312  		return errors.New("container: invalid abstraction")
   313  	}
   314  	option := &resolveOption{}
   315  	for _, op := range options {
   316  		err := op(option)
   317  		if err != nil {
   318  			return err
   319  		}
   320  	}
   321  	if receiverType.Kind() == reflect.Ptr {
   322  		elem := receiverType.Elem()
   323  		b, err := c.getBinding(elem, option.name)
   324  		if err != nil {
   325  			return errors.New("resolve type: " + receiverType.String() + " no concrete found for: " + elem.String())
   326  		}
   327  		args := b.specifiedParameters
   328  		if len(option.args) > 0 {
   329  			for i, v := range option.args {
   330  				args[i] = v
   331  			}
   332  		}
   333  		oldArgs := b.specifiedParameters
   334  		b.specifiedParameters = args
   335  		defer func() {
   336  			b.specifiedParameters = oldArgs
   337  		}()
   338  		instance, err := b.resolve(c)
   339  		if err != nil {
   340  			return err //errors.New("resolve type: " + receiverType.String() + " " + err.Error())
   341  		}
   342  		reflect.ValueOf(abstraction).Elem().Set(reflect.ValueOf(instance))
   343  		return nil
   344  	}
   345  	return errors.New("container: invalid abstraction")
   346  }
   347  
   348  // Call takes a function (receiver) with one or more arguments of the abstractions (interfaces).
   349  // It invokes the function (receiver) and passes the related implementations.
   350  func (c *Container) Call(function interface{}, options ...CallOption) ([]interface{}, error) {
   351  	receiverType := reflect.TypeOf(function)
   352  	if receiverType == nil || receiverType.Kind() != reflect.Func {
   353  		return nil, errors.New("container: invalid function")
   354  	}
   355  	callOption := &resolveOption{}
   356  	for _, op := range options {
   357  		err := op(callOption)
   358  		if err != nil {
   359  			return nil, err
   360  		}
   361  	}
   362  	return c.invoke(function, callOption.args, callOption.dependsOn, nil) //TODO optional
   363  }
   364  
   365  // Fill takes a struct and resolves the fields with the tag `optional:"true"` or `name:"dependOnName1"`
   366  func (c *Container) Fill(structure interface{}) error {
   367  	// 获取入参类型
   368  	receiverType := reflect.TypeOf(structure)
   369  	if receiverType == nil {
   370  		return errors.New("container: invalid structure")
   371  	}
   372  	if receiverType.Kind() == reflect.Ptr {
   373  		elem := receiverType.Elem()
   374  		if elem.Kind() == reflect.Struct {
   375  			s := reflect.ValueOf(structure).Elem()
   376  			for i := 0; i < s.NumField(); i++ {
   377  				// 获取第i个字段
   378  				f := s.Field(i)
   379  				fType := f.Type()
   380  				//如果是interface的数组,那么就填充所有实现
   381  				sliceFill := false
   382  				if f.Kind() == reflect.Slice && f.Type().Elem().Kind() == reflect.Interface {
   383  					sliceFill = true
   384  					fType = f.Type().Elem()
   385  				} else if f.Kind() != reflect.Interface { //只对interface类型执行Fill逻辑
   386  					continue
   387  				}
   388  				//是否是可选的
   389  				optional := false
   390  				if b, exist := s.Type().Field(i).Tag.Lookup("optional"); exist {
   391  					optional = strings.ToLower(b) == "true"
   392  				}
   393  				namedBinding, ok := c.bind[fType]
   394  				if !ok {
   395  					if optional {
   396  						continue
   397  					}
   398  					return errors.New("container: no concrete found for: " + f.Type().String())
   399  				}
   400  				if sliceFill {
   401  					for _, b := range namedBinding.namedBinding {
   402  						instance, _ := b.resolve(c)
   403  						ptr := reflect.NewAt(f.Type(), unsafe.Pointer(f.UnsafeAddr())).Elem()
   404  						ptr.Set(reflect.Append(ptr, reflect.ValueOf(instance)))
   405  					}
   406  					continue
   407  				}
   408  				b := namedBinding.defaultBinding
   409  				//指定了name字段说明该字段依赖的binding name
   410  				if name, exist := s.Type().Field(i).Tag.Lookup("name"); exist {
   411  					if concrete, exist := namedBinding.namedBinding[name]; exist {
   412  						b = concrete
   413  					} else {
   414  						return fmt.Errorf("container: cannot resolve %v field", s.Type().Field(i).Name)
   415  					}
   416  				}
   417  				//没有指定name,获得默认binding
   418  				instance, _ := b.resolve(c)
   419  				ptr := reflect.NewAt(f.Type(), unsafe.Pointer(f.UnsafeAddr())).Elem()
   420  				ptr.Set(reflect.ValueOf(instance))
   421  			}
   422  			return nil
   423  		}
   424  		return errors.New("container: invalid structure, input elem type:" + elem.Kind().String())
   425  	}
   426  	return errors.New("container: invalid structure, input type:" + receiverType.Kind().String())
   427  }
   428  
   429  // Reset deletes all the existing bindings and empties the container instance.
   430  func (c *Container) Reset() {
   431  	for k := range c.bind {
   432  		delete(c.bind, k)
   433  	}
   434  	for k := range c.alias {
   435  		delete(c.alias, k)
   436  	}
   437  }
   438  
   439  func (c *Container) Clone() *Container {
   440  	clone := &Container{
   441  		bind:  make(map[reflect.Type]*namedBinding, len(c.bind)),
   442  		alias: make(map[reflect.Type]reflect.Type, len(c.alias)),
   443  	}
   444  	for k, v := range c.bind {
   445  		clone.bind[k] = v.Clone()
   446  	}
   447  	for k, v := range c.alias {
   448  		clone.alias[k] = v
   449  	}
   450  	return clone
   451  }
   452  
   453  // container is the global repository of bindings
   454  var container = NewContainer()
   455  
   456  // Resolve takes an abstraction (interface reference) and fills it with the related implementation.
   457  func Resolve(abstraction interface{}, options ...ResolveOption) error {
   458  	return container.Resolve(abstraction, options...)
   459  }
   460  
   461  //Register register interface-> constructor
   462  func Register(constructor interface{}, options ...Option) error {
   463  	return container.Register(constructor, options...)
   464  }
   465  
   466  // Reset deletes all the existing bindings and empties the container instance.
   467  func Reset() {
   468  	container.Reset()
   469  }
   470  
   471  //Fill takes a struct and resolves the fields with the tag `optional:"true"` or `name:"dependOnName1"`
   472  //argument must be a struct point
   473  func Fill(structure interface{}) error {
   474  	return container.Fill(structure)
   475  }
   476  
   477  //Call invoke function that use interface as parameters
   478  func Call(function interface{}, options ...CallOption) ([]interface{}, error) {
   479  	return container.Call(function, options...)
   480  }
   481  
   482  //RegisterInstance register interface->instance into container
   483  func RegisterInstance(interfacePtr interface{}, instance interface{}, options ...Option) error {
   484  	return container.RegisterInstance(interfacePtr, instance, options...)
   485  }
   486  
   487  //RegisterSubInterface set sub interface map to another interface
   488  func RegisterSubInterface(subInterfacePtr interface{}, interfacePtr interface{}) error {
   489  	return container.RegisterSubInterface(subInterfacePtr, interfacePtr)
   490  }
   491  
   492  //SetDefaultBinding change default binding to another name
   493  func SetDefaultBinding(interfacePtr interface{}, defaultName string) error {
   494  	return container.SetDefaultBinding(interfacePtr, defaultName)
   495  }
   496  func isNil(i interface{}) bool {
   497  	vi := reflect.ValueOf(i)
   498  	if vi.Kind() == reflect.Ptr {
   499  		return vi.IsNil()
   500  	}
   501  	return false
   502  }
   503  func Clone() *Container {
   504  	return container.Clone()
   505  }