|
|
- // Copyright (c) Shenyang Leading Edge Intelligent Technology Co., Ltd. All rights reserved.
-
- package container
-
- import (
- "errors"
- "fmt"
- "reflect"
- "strings"
- )
-
- type DefaultComponentContainer struct {
- methodMapping map[string]func([]reflect.Value) []reflect.Value
- }
-
- func NewDefaultComponentContainer() *DefaultComponentContainer {
- return &DefaultComponentContainer{
- methodMapping: make(map[string]func([]reflect.Value) []reflect.Value),
- }
- }
-
- func (container *DefaultComponentContainer) RegisterService(factory interface{}) error {
-
- valueOfFactory := reflect.ValueOf(factory)
- typeOfFactory := valueOfFactory.Type()
- if typeOfFactory.Kind() != reflect.Func {
- return errors.New("工厂必须是func!")
- }
- if typeOfFactory.NumIn() != 0 {
- return errors.New("工厂不能有参数!")
- }
- if typeOfFactory.NumOut() < 1 {
- return errors.New("工厂必值需有返回值!")
- }
- if typeOfFactory.NumOut() > 1 {
- return errors.New("工厂只能有一个返回值!")
- }
- if typeOfFactory.Out(0).Kind() != reflect.Interface {
- return errors.New("工厂的返回值必需是interface!")
- }
- serviceType := typeOfFactory.Out(0)
- serviceName := serviceType.Name()
- if serviceType.Kind() != reflect.Interface {
- return errors.New(fmt.Sprintf("服务类型必须是接口! 服务: %s", serviceName))
- }
- if !strings.HasSuffix(serviceName, ServiceNameSuffix) {
- return errors.New(fmt.Sprintf("服务%s接口名称的后缀不是%s!", serviceType.Name(), ServiceNameSuffix))
- }
- packageList := strings.Split(serviceType.PkgPath(), PathSeparator)
- servicePackagePath := ""
- for index, packageName := range packageList {
- if strings.ToLower(packageName) == ServicesPackageName {
- servicePackagePath = strings.Join(packageList[index+1:], PathSeparator)
- break
- }
- }
- if servicePackagePath == "" {
- return errors.New(fmt.Sprintf("服务%s不在包%s或他的子包之下!", serviceType.Name(), ServicesPackageName))
- }
- for i := 0; i < serviceType.NumMethod(); i++ {
- method := serviceType.Method(i)
- serviceValue := valueOfFactory.Call(emptyParameters)[0]
- methodValue := serviceValue.MethodByName(method.Name)
- methodFullName := fmt.Sprintf("%s/%s.%s", servicePackagePath, serviceType.Name(), method.Name)
- container.methodMapping[methodFullName] = methodValue.Call
- }
- return nil
- }
-
- func (container *DefaultComponentContainer) GetServiceCaller(methodFullName string) func([]reflect.Value) []reflect.Value {
- caller, ok := container.methodMapping[methodFullName]
- if ok {
- return caller
- }
- return nil
- }
|