예제 #1
0
        public static string GetServiceRoute(this Type serviceType)
        {
            if (serviceType == null)
            {
                throw new ArgumentNullException("serviceType");
            }

            string template = string.Empty;

            ServiceRouteAttribute attribute = serviceType.GetCustomAttributes(typeof(ServiceRouteAttribute), true)
                                              .OfType <ServiceRouteAttribute>()
                                              .FirstOrDefault();

            if (attribute != null)
            {
                template = attribute.Route;
            }

            return(template);
        }
예제 #2
0
        public IServiceEntryContainer AddServices(Type[] types)
        {
            IEnumerable <Type> serviceTypes = types
                                              .Where(x => x.GetMethods().Any(y => y.GetCustomAttribute <ServiceAttribute>() != null)).Distinct();

            foreach (Type type in serviceTypes)
            {
                ServiceRouteAttribute   routeTemplate = type.GetCustomAttribute <ServiceRouteAttribute>();
                ServiceVersionAttribute version       = type.GetCustomAttribute <ServiceVersionAttribute>();

                foreach (MethodInfo methodInfo in type.GetTypeInfo().GetMethods().Where(x => x.GetCustomAttributes <ServiceDescAttribute>().Any()))
                {
                    ServiceDesc desc = new ServiceDesc();
                    IEnumerable <ServiceDescAttribute> descriptorAttributes = methodInfo.GetCustomAttributes <ServiceDescAttribute>();

                    IEnumerable <FilterBaseAttribute> filters = methodInfo.GetCustomAttributes <FilterBaseAttribute>();

                    foreach (ServiceDescAttribute attr in descriptorAttributes)
                    {
                        attr.Apply(desc);
                    }

                    desc.ReturnDesc = GetReturnDesc(methodInfo);

                    if (string.IsNullOrEmpty(desc.HttpMethod))
                    {
                        desc.HttpMethod = GetHttpMethod(methodInfo);
                    }

                    desc.Parameters = _serializer.Serialize <string>(GetParameters(methodInfo));

                    string route = string.Empty;

                    if (routeTemplate != null)
                    {
                        if (version != null && routeTemplate.RouteTemplate.Contains("{version}"))
                        {
                            route        = routeTemplate.RouteTemplate.Replace("{version}", version.Version);
                            desc.Version = version.Version;
                        }
                        else
                        {
                            route = routeTemplate.RouteTemplate;
                        }
                    }
                    if (string.IsNullOrEmpty(desc.Id))
                    {
                        desc.Id = _serviceIdGenerate.GenerateServiceId(methodInfo, route, desc).ToLower();
                    }

                    FastExecutor.FastExecutorHandler fastInvoker = GetHandler(desc.Id, methodInfo);

                    ParameterInfo[] methodParas = methodInfo.GetParameters();
                    if (routeTemplate != null)
                    {
                        desc.RoutePath = ServiceRoute.ParseRoutePath(route, type.Name, methodInfo.Name, methodParas, type.IsInterface);
                    }

                    ServiceEntry service = new ServiceEntry
                    {
                        Descriptor = desc,
                        Parameters = methodParas,

                        Func = (context) =>
                        {
                            object instance = GetInstance(methodInfo.DeclaringType, context.RemoteInvokeMessage.Payload);

                            Dictionary <Type, object> dic = new Dictionary <Type, object>();
                            foreach (ParameterInfo p in methodParas)
                            {
                                context.RemoteInvokeMessage.Parameters.TryGetValue(p.Name.ToLower(), out object value);
                                object parameter;
                                Type   paraType = p.ParameterType;
                                if (typeof(List <ServerFile>) == paraType)
                                {
                                    List <FileData>   fileData = _typeConvertProvider.Convert(value, paraType) as List <FileData>;
                                    List <ServerFile> files    = new List <ServerFile>();
                                    foreach (FileData file in fileData)
                                    {
                                        ServerFile serverFile = new ServerFile
                                        {
                                            Data     = Convert.FromBase64String(file.Data),
                                            FileName = file.FileName
                                        };
                                        files.Add(serverFile);
                                    }
                                    parameter = files;
                                }
                                else
                                {
                                    parameter = _typeConvertProvider.Convert(value, paraType) ?? null;
                                }
                                dic[paraType] = parameter;
                            }

                            FilterContext filterContext = new FilterContext()
                            {
                                Payload          = context.RemoteInvokeMessage.Payload,
                                Descriptor       = desc,
                                ServiceArguments = dic
                            };

                            filters?.Aggregate(filterContext, (filtercontext, filter) =>
                            {
                                filter.Container = _container;
                                if (filtercontext.Result == null)
                                {
                                    filter.OnActionExecuting(filtercontext);
                                }
                                return(filtercontext);
                            });

                            if (filterContext.Result == null)
                            {
                                filterContext.Result = fastInvoker(instance, dic.Select(o => o.Value).ToArray());

                                filters?.Aggregate(filterContext, (filtercontext, filter) =>
                                {
                                    filter.OnActionExecuted(filtercontext);
                                    return(filtercontext);
                                });
                            }

                            return(Task.FromResult(filterContext.Result));
                        }
                    };

                    _services.Add(service);
                }
            }

            return(this);
        }