예제 #1
0
        /// <summary>
        /// 初始化接口描述
        /// </summary>
        /// <param name="type"></param>
        /// <param name="method"></param>
        public ApiDescriptor(MethodInfo method, ApiClassDescriptor apiClass, IDictionary <string, object> settings)
        {
            ApiClass   = apiClass ?? throw new ArgumentNullException(nameof(apiClass));
            Container  = apiClass.Container;
            Method     = method ?? throw new ArgumentNullException(nameof(method));
            Settings   = settings ?? throw new ArgumentNullException(nameof(settings));
            Parameters = method.GetParameters().Select(it => new ApiParameterDescriptor(it, this)).AsReadOnly();
            Name       = method.Name;
            _invoker   = CreateInvoker(method);

            var filters = new List <ApiFilterAttribute>();

            foreach (ApiFilterAttribute filter in method.GetCustomAttributes <ApiFilterAttribute>().FiltrateAttribute(Container.Provider, true)
                     .Union(method.DeclaringType.GetTypeInfo().GetCustomAttributes <ApiFilterAttribute>().FiltrateAttribute(Container.Provider, true))
                     .Union(Container.Filters.FiltrateAttribute(Container.Provider, true)))
            {
                if (filters.Any(a => a.Match(filter)) == false)
                {
                    filters.Add(filter);
                }
            }

            filters.Sort((a, b) => a.OrderNumber.CompareTo(b.OrderNumber));
            Filters = new ReadOnlyCollection <ApiFilterAttribute>(filters);
        }
예제 #2
0
        /// <summary>
        ///     初始化接口属性描述
        /// </summary>
        /// <param name="api"></param>
        /// <param name="property"></param>
        private ApiPropertyDescriptor(PropertyInfo property, ApiClassDescriptor apiclass, IDictionary <string, object> settings)
        {
            ApiClass  = apiclass ?? throw new ArgumentNullException(nameof(apiclass));
            Container = apiclass.Container;
            Settings  = settings ?? throw new ArgumentNullException(nameof(settings));
            Property  = property ?? throw new ArgumentNullException(nameof(property));

            Name         = property.Name;
            PropertyType = property.PropertyType;
            var defattr = property.GetCustomAttribute <DefaultValueAttribute>(true);

            if (defattr != null)
            {
                DefaultValue    = defattr.Value;
                HasDefaultValue = true;
            }


            var setter = (IServiceProvider)Activator.CreateInstance(typeof(SetterProvider <,>).GetTypeInfo().MakeGenericType(property.DeclaringType, property.PropertyType), property);

            Setter = (Action <object, object>)setter.GetService(typeof(Action <object, object>));


            var validations = new List <DataValidationAttribute>();

            foreach (DataValidationAttribute filter in property.GetCustomAttributes <DataValidationAttribute>().Reverse()
                     .Union(property.DeclaringType.GetTypeInfo().GetCustomAttributes <DataValidationAttribute>().Reverse())
                     .Union(Container.Validations.Reverse()))
            {
                if (validations.Any(a => a.Match(filter)) == false && filter.IsAllowType(PropertyType))
                {
                    validations.Add(filter);
                }
            }
            validations.Reverse();
            DataValidations = validations.AsReadOnly();

            var modifications = new List <DataModificationAttribute>();

            foreach (DataModificationAttribute filter in property.GetCustomAttributes <DataModificationAttribute>().Reverse()
                     .Union(property.DeclaringType.GetTypeInfo().GetCustomAttributes <DataModificationAttribute>().Reverse())
                     .Union(Container.Modifications.Reverse()))
            {
                if (modifications.Any(a => a.Match(filter)) == false && filter.IsAllowType(PropertyType))
                {
                    modifications.Add(filter);
                }
            }
            modifications.Reverse();
            DataModifications = modifications.AsReadOnly();
        }
예제 #3
0
 /// <summary>
 /// 创建API属性描述,如果属性不是API属性,则返null
 /// </summary>
 /// <param name="property"></param>
 /// <param name="apiclass"></param>
 /// <returns></returns>
 internal static ApiPropertyDescriptor Create(PropertyInfo property, ApiClassDescriptor apiclass)
 {
     if (property.CanWrite && property.SetMethod.IsPublic && property.GetIndexParameters().Length == 0)
     {
         var attrs = property.GetCustomAttributes <ApiPropertyAttribute>();
         if (attrs.Any() == false)
         {
             return(null);
         }
         var settings = apiclass.Container.Provider.ParseSetting(attrs);
         return(new ApiPropertyDescriptor(property, apiclass, settings));
     }
     return(null);
 }
예제 #4
0
 /// <summary>
 /// 创建API描述,如果方法不是API则返回null
 /// </summary>
 /// <param name="method">同于创建API的方法</param>
 /// <param name="apiclass">方法所在类的描述</param>
 /// <returns></returns>
 internal static ApiDescriptor Create(MethodInfo method, ApiClassDescriptor apiclass)
 {
     if (method.IsPublic && method.IsGenericMethodDefinition == false)
     {
         var attrs    = method.GetCustomAttributes <ApiAttribute>();
         var settings = apiclass.Container.Provider.ParseSetting(attrs);
         if (settings == null)
         {
             return(null);
         }
         return(new ApiDescriptor(method, apiclass, settings));
     }
     return(null);
 }
예제 #5
0
        /// <summary>
        /// 构建一个ApiClass描述,如果<paramref name="type"/>不是ApiClass则返回null
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        internal static ApiClassDescriptor Create(Type type, ApiContainer container)
        {
            var typeInfo = type.GetTypeInfo();

            if (!typeInfo.IsClass || typeInfo.IsAbstract || typeInfo.IsGenericTypeDefinition) //排除抽象类和泛型定义类型
            {
                return(null);
            }

            if (typeInfo.DeclaredMethods.Any(m => m.IsDefined(typeof(ApiAttribute))) == false)
            {
                return(null);
            }

            var classAttrs = typeInfo.GetCustomAttributes <ApiClassAttribute>().ToArray();

            var settings = container.Provider.ParseSetting(classAttrs) ?? new Dictionary <string, object>(StringComparer.OrdinalIgnoreCase);

            var apiclass = new ApiClassDescriptor(type, container, settings);

            var propAttrs = typeInfo.DeclaredProperties
                            .Select(it => ApiPropertyDescriptor.Create(it, apiclass))
                            .Where(it => it != null);

            apiclass._properties.AddRange(propAttrs);

            var apis = typeInfo.DeclaredMethods
                       .Select(it => ApiDescriptor.Create(it, apiclass))
                       .Where(it => it != null);

            apiclass._apis.AddRange(apis);

            if (classAttrs.Length == 0 && apiclass._properties.Count == 0 && apiclass._apis.Count == 0)
            {
                return(null);
            }

            return(apiclass);
        }
예제 #6
0
 /// <summary>
 /// 添加一个ApiClass描述
 /// </summary>
 /// <param name="apiclass"></param>
 internal void AddApiCalss(ApiClassDescriptor apiclass)
 => _types.Add(apiclass);