You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

85 lines
2.5 KiB

// 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
}