Example #1
0
        /// <summary>
        /// 创建上下文
        /// </summary>
        /// <param name="apiDescriptor"> api描述 </param>
        /// <param name="dataProvider"> 数据提供程序 </param>
        /// <param name="resultUpdater"> 返回值更新程序 </param>
        /// <returns>如果编译失败,返回异常信息</returns>
        public ApiCallContext CreateContext(ApiDescriptor apiDescriptor, IApiDataProvider dataProvider, out IResultUpdater resultUpdater)
        {
            if (ApiCollection.Apis.Contains(apiDescriptor ?? throw new ArgumentNullException(nameof(apiDescriptor))) == false)
            {
                throw new ArgumentException("API描述不属于当前容器", nameof(apiDescriptor));
            }
            var            logger  = Provider.Logger.GetUsableService(false); //获取日志服务
            ApiCallContext context = null;

            try
            {
                var instance = apiDescriptor.Method.IsStatic
                    ? null
                    : dataProvider.GetApiInstance(apiDescriptor) ??
                               Activator.CreateInstance(apiDescriptor.ApiClass.Type);
                resultUpdater = Provider.CreateResultUpdater() ?? new ResultProvider();
                var session = dataProvider.GetSession();
                context = new ApiCallContext(instance, apiDescriptor.Method, resultUpdater, session, logger);
                context.Data["$ResultProvider"] = resultUpdater;
                context.Data["$ApiContainer"]   = this;
                context.Data["$ApiDescriptor"]  = apiDescriptor;

                logger?.Append(new LogItem()
                {
                    Context = context,
                    Level   = LogLevel.Debug,
                    Message = "创建上下文",
                    Title   = "系统",
                });

                if (session != null)
                {
                    EventCaller.Invoke(GlobalEvents.OnBeginRequest, context);
                }

                var parameters = context.Parameters;
                var properties = context.Properties;

                //属性
                if (apiDescriptor.Method.IsStatic == false)
                {
                    foreach (var p in apiDescriptor.Properties)
                    {
                        var result = dataProvider.GetProperty(p);

                        if (result.Error != null && result.Exists)
                        {
                            properties.Add(p.Name, result.Error);
                            resultUpdater.SetException(result.Error);
                            return(context);
                        }

                        if (result.Exists || p.HasDefaultValue == false)
                        {
                            var value = result.Exists ? result.Value : null;
                            if (p.DataModifications.Count > 0)
                            {
                                p.DataModifications.ForEach(it => it.Modifies(ref value, context)); //变更数据
                            }
                            Modifier.Modifies(value, context);
                            if (result.Exists)
                            {
                                properties.Add(p.Name, value);
                                p.Setter(instance, value);
                            }
                            if (p.DataValidations.Count > 0)
                            {
                                var ex = p.DataValidations.FirstOrDefault(it => it.IsValid(value, context) == false)?
                                         .GetException(p.Name, value, context)
                                         ?? Validator.IsValid(value, context, true); //数据验证
                                if (ex != null)
                                {
                                    resultUpdater.SetException(ex);
                                    return(context);
                                }
                            }
                        }
                        else
                        {
                            properties.Add(p.Name, p.DefaultValue);
                            p.Setter(instance, p.DefaultValue);
                        }
                    }
                }

                //参数
                foreach (var p in apiDescriptor.Parameters)
                {
                    if (p.ParameterType == typeof(ISession))
                    {
                        parameters.Add(p.Name, session);
                        continue;
                    }
                    if (p.ParameterType == typeof(ApiCallContext))
                    {
                        parameters.Add(p.Name, context);
                        continue;
                    }
                    if (p.ParameterType == typeof(ILogger))
                    {
                        parameters.Add(p.Name, logger);
                        continue;
                    }

                    var result = dataProvider.GetParameter(p);

                    if (result.Error != null && result.Exists)
                    {
                        parameters.Add(p.Name, result.Error);
                        resultUpdater.SetException(result.Error);
                        return(context);
                    }

                    if (result.Exists)
                    {
                        var value = result.Value;
                        if (p.DataModifications.Count > 0)
                        {
                            p.DataModifications.ForEach(it => it.Modifies(ref value, context)); //变更数据
                        }
                        Modifier.Modifies(value, context);
                        parameters.Add(p.Name, value);
                        if (p.DataValidations.Count > 0)
                        {
                            var ex = p.DataValidations.FirstOrDefault(it => it.IsValid(value, context) == false)?.GetException(p.Name, value, context)
                                     ?? Validator.IsValid(value, context, true); //数据验证
                            if (ex != null)
                            {
                                resultUpdater.SetException(ex);
                                return(context);
                            }
                        }
                    }
                    else if (p.HasDefaultValue)
                    {
                        parameters.Add(p.Name, p.DefaultValue);
                    }
                    else
                    {
                        var ex = ApiException.ArgumentMissing(p.Name);
                        parameters.Add(p.Name, ex);
                        resultUpdater.SetException(ex);
                        return(context);
                    }
                }

                EventCaller.Invoke(GlobalEvents.OnApiDataParsed, context);
                return(context);
            }
            catch (Exception ex)
            {
                logger?.Append(new LogItem()
                {
                    Context   = context,
                    Exception = ex,
                    Level     = LogLevel.Critical,
                    Message   = "未处理异常",
                    Title     = "系统",
                });
                EventCaller.Invoke(GlobalEvents.OnUnprocessException, context);
                throw;
            }
            finally
            {
                if (context?.IsError == true)
                {
                    var ex = context.Exception.GetRealException();
                    if (ex is ApiException e)
                    {
                        context.Warning(e.Message, "逻辑异常");
                        if (e.InnerException != null)
                        {
                            context.Warning(e.InnerException, "内部逻辑异常");
                        }
                        EventCaller.Invoke(GlobalEvents.OnApiException, context);
                    }
                    else
                    {
                        context.Error(context.Exception, "服务器内部错误");
                        EventCaller.Invoke(GlobalEvents.OnUnprocessException, context);
                    }
                }
            }
        }