苏州瑞玛APS项目web后台
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.

76 lines
2.5 KiB

  1. // Copyright (c) Shenyang Leading Edge Intelligent Technology Co., Ltd. All rights reserved.
  2. package container
  3. import (
  4. "errors"
  5. "fmt"
  6. "reflect"
  7. "strings"
  8. )
  9. type DefaultComponentContainer struct {
  10. methodMapping map[string]func([]reflect.Value) []reflect.Value
  11. }
  12. func NewDefaultComponentContainer() *DefaultComponentContainer {
  13. return &DefaultComponentContainer{
  14. methodMapping: make(map[string]func([]reflect.Value) []reflect.Value),
  15. }
  16. }
  17. func (container *DefaultComponentContainer) RegisterService(factory interface{}) error {
  18. valueOfFactory := reflect.ValueOf(factory)
  19. typeOfFactory := valueOfFactory.Type()
  20. if typeOfFactory.Kind() != reflect.Func {
  21. return errors.New("工厂必须是func!")
  22. }
  23. if typeOfFactory.NumIn() != 0 {
  24. return errors.New("工厂不能有参数!")
  25. }
  26. if typeOfFactory.NumOut() < 1 {
  27. return errors.New("工厂必值需有返回值!")
  28. }
  29. if typeOfFactory.NumOut() > 1 {
  30. return errors.New("工厂只能有一个返回值!")
  31. }
  32. if typeOfFactory.Out(0).Kind() != reflect.Interface {
  33. return errors.New("工厂的返回值必需是interface!")
  34. }
  35. serviceType := typeOfFactory.Out(0)
  36. serviceName := serviceType.Name()
  37. if serviceType.Kind() != reflect.Interface {
  38. return errors.New(fmt.Sprintf("服务类型必须是接口! 服务: %s", serviceName))
  39. }
  40. if !strings.HasSuffix(serviceName, ServiceNameSuffix) {
  41. return errors.New(fmt.Sprintf("服务%s接口名称的后缀不是%s!", serviceType.Name(), ServiceNameSuffix))
  42. }
  43. packageList := strings.Split(serviceType.PkgPath(), PathSeparator)
  44. servicePackagePath := ""
  45. for index, packageName := range packageList {
  46. if strings.ToLower(packageName) == ServicesPackageName {
  47. servicePackagePath = strings.Join(packageList[index+1:], PathSeparator)
  48. break
  49. }
  50. }
  51. if servicePackagePath == "" {
  52. return errors.New(fmt.Sprintf("服务%s不在包%s或他的子包之下!", serviceType.Name(), ServicesPackageName))
  53. }
  54. for i := 0; i < serviceType.NumMethod(); i++ {
  55. method := serviceType.Method(i)
  56. serviceValue := valueOfFactory.Call(emptyParameters)[0]
  57. methodValue := serviceValue.MethodByName(method.Name)
  58. methodFullName := fmt.Sprintf("%s/%s.%s", servicePackagePath, serviceType.Name(), method.Name)
  59. container.methodMapping[methodFullName] = methodValue.Call
  60. }
  61. return nil
  62. }
  63. func (container *DefaultComponentContainer) GetServiceCaller(methodFullName string) func([]reflect.Value) []reflect.Value {
  64. caller, ok := container.methodMapping[methodFullName]
  65. if ok {
  66. return caller
  67. }
  68. return nil
  69. }