// Copyright (c) Shenyang Leading Edge Intelligent Technology Co., Ltd. All rights reserved. package container import ( "errors" "fmt" "github.com/kataras/iris/v12/context" "github.com/kataras/iris/v12/core/router" "leit.com/LAPP_CHEERSSON_BACKEND/global" "reflect" "strings" ) const ( ServicesPackageName = "services" ServiceNameSuffix = "Service" PathSeparator = "/" HttpPost HttpMethod = "POST" HttpPut HttpMethod = "POU" HttpGet HttpMethod = "Get" HttpDelete HttpMethod = "DELETE" ) var ServiceNameSuffixLength = len([]rune(ServiceNameSuffix)) type HttpMethod string type ( // 调用器 // 参数 // 1.参数列表 // 返回值: // 1.返回值列表 Caller = func([]reflect.Value) []reflect.Value // 调用器工厂 // 参数 // 1.会话标识 // 2.用户信息 // 返回值: // 1.调用器 // 2.错误 CallerFactory = func(string, *global.User) (Caller, error) // 路由 Router = context.Handler // 路由创建器 // 参数 // 1.会话管理器 // 2.服务类型 // 3.服务方法名 // 3.服务方法类型 // 返回值: // 1.HTTP请求方法 // 2.附加路径 // 3.路由 // 4.错误 RouterBuilder = func(CallerFactory, string, reflect.Type) (HttpMethod, string, Router, error) ) // *SessionContext类型常量 var sessionContextType = reflect.TypeOf((*SessionContext)(nil)) // 空参数列表 var emptyParameters []reflect.Value // Factory零值 var zeroOfFactory = Factory(reflect.ValueOf(nil)) // *error 类型常量 var errorType = reflect.TypeOf((*error)(nil)).Elem() // *RequestContext类型常量 var RequestContextType = reflect.TypeOf((*RequestContext)(nil)) // 无会话(XORM会话)上下文 var ContextOfNoSession = NewNoSessionBrokerBuilder() // 新会话(XORM会话)上下文 var ContextOfNewSession = NewNewSessionBrokerBuilder() // 新事务代理创建器上下文 var ContextOfNewTransaction = NewNewTransactionBrokerBuilder() // //// 组件信息管理器 //var currentInformationManager = NewInformationManager() // 解析组件工厂,返回:组件工厂Value,组件模块名,组件接口,错误 // 参数 // 1.工厂方法 // 返回值: // 1.组件工厂 // 2.组件接口类型 // 异常: // 1.工厂不能为空 // 2.工厂必须是func // 3.工厂不能有参数 // 4.工厂必值需有返回值 // 5.工厂只能有一个返回值 // 6.工厂的返回值必需是interface func parseFactory(factory interface{}) (Factory, Interface) { if factory == nil { panic(fmt.Sprintf("工厂不能为空!")) } valueOfFactory := reflect.ValueOf(factory) typeOfFactory := valueOfFactory.Type() if typeOfFactory.Kind() != reflect.Func { panic(fmt.Sprintf("工厂必须是func!")) } if typeOfFactory.NumIn() != 0 { panic(fmt.Sprintf("工厂不能有参数!")) } if typeOfFactory.NumOut() < 1 { panic(fmt.Sprintf("工厂必值需有返回值!")) } if typeOfFactory.NumOut() > 1 { panic(fmt.Sprintf("工厂只能有一个返回值!")) } if typeOfFactory.Out(0).Kind() != reflect.Interface { panic(fmt.Sprintf("工厂的返回值必需是interface!")) } componentType := typeOfFactory.Out(0) return Factory(valueOfFactory), componentType } // Caller相等性判断 // 参数 // 1.比较对象1 // 3.比较对象2 // 返回值: // 1.判断结果 func CallerEqual(caller1 Caller, caller2 Caller) bool { if caller1 == nil { if caller2 == nil { return true } else { return false } } else { if caller2 == nil { return false } else { return reflect.ValueOf(caller1).Pointer() == reflect.ValueOf(caller2).Pointer() } } } var GlobalInformations = NewInformationManager() // 注册路由 // 参数: // 1.路由分组 // 2.组件信息管理器 // 3.事务句柄工厂 // 返回值: // 1.错误 // 异常: // 1.组件信息管理器不能为空 // 2.事务句柄工厂不能为空 // 3.服务不在包或他的子包之下 // 4.组件接口名称的后缀不正确 func RegisterRoutes(party router.Party, defaultRouterBuilder RouterBuilder, informationManager InformationManager, transactionHandlerFactory TransactionHandlerFactory) { sessionManager := NewSessionManager(informationManager, transactionHandlerFactory) groups := make(map[string][]*ServiceInformation, 10) for _, information := range informationManager.Items() { if serviceInformation, ok := information.(*ServiceInformation); ok { packagePath := serviceInformation.Interface().PkgPath() group, ok := groups[packagePath] if !ok { group = make([]*ServiceInformation, 0, 10) } groups[packagePath] = append(group, serviceInformation) } for packagePath, group := range groups { packageList := strings.Split(packagePath, PathSeparator) moudlePath := "" for index, packageName := range packageList { if strings.ToLower(packageName) == ServicesPackageName { moudlePath = strings.Join(packageList[index+1:], PathSeparator) break } } if moudlePath == "" { panic(fmt.Sprintf("包%s不在包%s或他的子包之下!", packagePath, ServicesPackageName)) } moudleParty := party.Party(fmt.Sprintf("/%s", strings.ToLower(moudlePath))) for _, serviceInformation := range group { serviceType := serviceInformation.Interface() serviceName := serviceType.Name() if !strings.HasSuffix(serviceName, ServiceNameSuffix) { panic(fmt.Sprintf("组件%s接口名称的后缀不是%s!", serviceName, ServiceNameSuffix)) } runesOfserviceName := []rune(serviceName) serviceParty := moudleParty.Party(fmt.Sprintf("/%s", strings.ToLower(string(runesOfserviceName[:len(runesOfserviceName)-ServiceNameSuffixLength])))) for _, serviceMethodInformation := range serviceInformation.Methods() { methodName := serviceMethodInformation.MethodName() routerBuilder := serviceMethodInformation.RouterBuilder() if routerBuilder == nil { routerBuilder = defaultRouterBuilder } var callerFactory = func(sessionId string, user *global.User) (Caller, error) { session, err := sessionManager.GetSession(sessionId, user) if err != nil { return nil, err } serviceHandler, ok := session.Handlers().Handler(serviceType).(*ServiceHandler) if !ok { return nil, errors.New(fmt.Sprintf("竟然没找到服务组件句柄!")) } return serviceHandler.Method(methodName).Caller(), nil } serviceMethodName := fmt.Sprintf("%s.%s", serviceName, methodName) httpMethod, addedPath, irisRouter, err := routerBuilder(callerFactory, serviceMethodName, serviceMethodInformation.MethodType()) if err != nil { panic(err.Error()) } serviceParty.Handle(string(httpMethod), fmt.Sprintf("/%s", strings.ToLower(methodName)+addedPath), irisRouter) } } } } }