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 }