// 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{contextType: reflect.ValueOf(context)})
|
|
if err != nil {
|
|
return ZeroInstance, err
|
|
}
|
|
return Instance(instanceValue), nil
|
|
}
|