// Copyright (c) Shenyang Leading Edge Intelligent Technology Co., Ltd. All rights reserved. package container import ( "errors" "fmt" "reflect" "strings" ) // 组件实例工厂 type Factory reflect.Value // 设置字段值 // 参数 // 1.需要设置字段值的实例 // 2.可以设置的类型和值的映射 // 返回值: // 1.错误 func (factory Factory) setReferences(instance reflect.Value, references map[reflect.Type]reflect.Value) error { implement := reflect.ValueOf(instance.Interface()) implementPointerType := implement.Type() implementType := implementPointerType.Elem() for i := 0; i < implementType.NumField(); i++ { field := implementType.Field(i) if reference, ok := references[field.Type]; ok { methodName := fmt.Sprintf("Set%s", strings.Title(field.Name)) method, ok := implementPointerType.MethodByName(methodName) if ok { methodType := method.Type // 从结构体指针类型获取方法类型,Receiver算作入参 if methodType.NumIn() != 2 { return errors.New(fmt.Sprintf("设置器参数数量不正确!")) } if methodType.NumOut() != 0 { return errors.New(fmt.Sprintf("设置器返回值数量不正确!")) } if methodType.In(1) != field.Type { return errors.New(fmt.Sprintf("设置器类型不正确!")) } implement.MethodByName(methodName).Call([]reflect.Value{reference}) } } } return nil } // 创建实例 // 参数 // 1.会话上下文 // 返回值: // 1.调用器 // 2.错误 func (factory Factory) Create(context *SessionContext) (Instance, error) { if context == nil { return ZeroInstance, errors.New(fmt.Sprintf("会话上下文不能为空!")) } instanceValue := reflect.Value(factory).Call(emptyParameters)[0] actualValue := instanceValue if instanceValue.Kind() == reflect.Interface { actualValue = reflect.ValueOf(instanceValue.Interface()) } // 检查空接口 if actualValue.Kind() == reflect.Invalid { return ZeroInstance, errors.New(fmt.Sprintf("实际值不能是空接口!")) } if actualValue.Kind() != reflect.Ptr { return Instance(instanceValue), nil } // 检查空指针,首先要保证是指针 if actualValue.IsNil() { return ZeroInstance, errors.New(fmt.Sprintf("实际值不能是空指针!")) } actualType := actualValue.Type() if actualType.Elem().Kind() != reflect.Struct { return Instance(instanceValue), nil } err := factory.setReferences(actualValue, map[reflect.Type]reflect.Value{sessionContextType: reflect.ValueOf(context)}) if err != nil { return ZeroInstance, err } return Instance(instanceValue), nil }