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