/// <summary> /// 查找站点 /// </summary> public void FindZeroObjects() { ZeroTrace.SystemLog("FindZeroObjects", Assembly.Location); Type[] types; try { types = Assembly.GetTypes().Where(p => p.IsSupperInterface(typeof(IZeroObject))).ToArray(); } catch (ReflectionTypeLoadException ex) { types = ex.Types.Where(p => p != null).ToArray(); ZeroTrace.WriteException("FindZeroObjects:GetTypes", ex); } try { foreach (var type in types) { XmlMember.Find(type); ZeroApplication.RegistZeroObject(type.CreateObject() as IZeroObject); } } catch (Exception ex) { ZeroTrace.WriteException("FindZeroObjects:RegistZeroObject", ex); } }
/// <summary> /// 查找API /// </summary> public void FindApies() { XmlMember.Load(Assembly); StationInfo.Add(StationName, _defStation = new StationDocument { Name = StationName }); var types = Assembly.GetTypes().Where(p => p.IsSubclassOf(typeof(ApiController))).ToArray(); foreach (var type in types) { FindApi(type, false); } RegistToZero(); RegistDocument(); }
private TypeDocument ReadEntity(Type type, string name) { if (type == typeof(void)) { return(null); } if (!IsLetter(type.Name[0])) { return(null); } var typeDocument = new TypeDocument { Name = name, TypeName = ReflectionHelper.GetTypeName(type), ClassName = ReflectionHelper.GetTypeName(type), ObjectType = ObjectType.Object }; typeDocument.Copy(XmlMember.Find(type)); ReadEntity(typeDocument, type); return(typeDocument); }
/// <summary> /// 查找API /// </summary> /// <param name="type"></param> /// <param name="onlyDoc"></param> private void FindApi(Type type, bool onlyDoc) { if (type.IsAbstract) { return; } StationDocument station; var sa = type.GetCustomAttribute <StationAttribute>(); if (sa != null) { if (!StationInfo.TryGetValue(sa.Name, out station)) { StationInfo.Add(sa.Name, station = new StationDocument { Name = sa.Name }); } } else { station = _defStation; } //station.Copy(XmlMember.Find(type)); string routeHead = null; var attrib = type.GetCustomAttribute <RouteAttribute>(); if (attrib != null) { routeHead = attrib.Name; } else { var attrib2 = type.GetCustomAttribute <RoutePrefixAttribute>(); if (attrib2 != null) { routeHead = attrib2.Name; } } if (string.IsNullOrWhiteSpace(routeHead)) { routeHead = null; } else { routeHead = routeHead.Trim(' ', '\t', '\r', '\n', '/') + "/"; } var methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); var xdoc = XmlMember.Find(type); foreach (var method in methods) { var route = method.GetCustomAttribute <RouteAttribute>(); if (route == null) { //ZeroTrace.WriteError("ApiDiscover", "exclude", station.Name, type.Name, method.Name); continue; } if (method.Name.Length > 4 && (method.Name.IndexOf("get_") == 0 || method.Name.IndexOf("set_") == 0)) { continue; } if (method.GetParameters().Length > 1) { //ZeroTrace.WriteError("ApiDiscover", "argument size must 0 or 1", station.Name, type.Name, method.Name); continue; } var name = route?.Name == null ? $"{routeHead}{method.Name}" : $"{routeHead}{route.Name.Trim(' ', '\t', '\r', '\n', '/')}"; var accessOption = method.GetCustomAttribute <ApiAccessOptionFilterAttribute>(); var ca = method.GetAttribute <CategoryAttribute>(); var api = new ApiActionInfo { Name = method.Name, ApiName = route?.Name ?? method.Name, RouteName = name, Category = ca?.Category ?? xdoc?.Caption, AccessOption = accessOption?.Option ?? ApiAccessOption.Public | ApiAccessOption.ArgumentCanNil, ResultInfo = ReadEntity(method.ReturnType, "result") }; var doc = XmlMember.Find(type, method.Name, "M"); api.Copy(doc); var arg = method.GetParameters().FirstOrDefault(); api.HaseArgument = arg != null; //动态生成并编译 if (api.HaseArgument) { api.ArgumentInfo = ReadEntity(arg.ParameterType, "argument") ?? new TypeDocument(); api.ArgumentInfo.Name = arg.Name; if (doc != null) { api.ArgumentInfo.Caption = doc.Arguments.Values.FirstOrDefault(); } if (!onlyDoc) { api.ArgumenType = arg.ParameterType; api.ArgumentAction = CreateFunc <IApiArgument, IApiResult>(type.GetTypeInfo(), method.Name, arg.ParameterType.GetTypeInfo(), method.ReturnType.GetTypeInfo()); } } else if (!onlyDoc) { api.Action = CreateFunc <IApiResult>(type.GetTypeInfo(), method.Name, method.ReturnType.GetTypeInfo()); } station.Aips.Add(api.RouteName, api); } }
TypeDocument CheckMember(TypeDocument document, Type parent, MemberInfo member, Type memType, bool json, bool dc, bool checkBase = true) { if (document.Fields.ContainsKey(member.Name)) { return(null); } var jp = member.GetAttribute <JsonPropertyAttribute>(); var dm = member.GetAttribute <DataMemberAttribute>(); if (json) { var ji = member.GetAttribute <JsonIgnoreAttribute>(); if (ji != null) { return(null); } if (jp == null) { return(null); } } else if (dc) { var id = member.GetAttribute <IgnoreDataMemberAttribute>(); if (id != null) { return(null); } } var field = new TypeDocument(); var doc = XmlMember.Find(parent, member.Name); field.Copy(doc); bool isArray = false; bool isDictionary = false; try { Type type = memType; if (memType.IsArray) { isArray = true; type = type.Assembly.GetType(type.FullName.Split('[')[0]); } else if (type.IsGenericType) { if (memType.IsSupperInterface(typeof(ICollection <>))) { isArray = true; type = type.GetGenericArguments()[0]; } else if (memType.IsSupperInterface(typeof(IDictionary <,>))) { var fields = type.GetGenericArguments(); field.Fields.Add("Key", ReadEntity(fields[0], "Key")); field.Fields.Add("Value", ReadEntity(fields[1], "Value")); isDictionary = true; checkBase = false; } } if (type.IsEnum) { if (checkBase) { field = ReadEntity(type, member.Name); } field.ObjectType = ObjectType.Base; field.IsEnum = true; } else if (type.IsBaseType()) { field.ObjectType = ObjectType.Base; } else if (!isDictionary) { if (checkBase) { field = ReadEntity(type, member.Name); } field.ObjectType = ObjectType.Object; } field.TypeName = ReflectionHelper.GetTypeName(type); } catch { field.TypeName = "object"; } if (isArray) { field.TypeName += "[]"; field.ObjectType = ObjectType.Array; } else if (isDictionary) { field.TypeName = "Dictionary"; field.ObjectType = ObjectType.Dictionary; } field.Name = member.Name; field.JsonName = member.Name; field.ClassName = ReflectionHelper.GetTypeName(memType); if (!string.IsNullOrWhiteSpace(dm?.Name)) { field.JsonName = dm.Name; } if (!string.IsNullOrWhiteSpace(jp?.PropertyName)) { field.JsonName = jp.PropertyName; } var rule = member.GetAttribute <DataRuleAttribute>(); if (rule != null) { field.CanNull = rule.CanNull; field.Regex = rule.Regex; if (rule.Min != long.MinValue) { field.Min = rule.Min; } if (rule.Max != long.MinValue) { field.Max = rule.Max; } if (rule.MinDate != DateTime.MinValue) { field.MinDate = rule.MinDate; } if (rule.MaxDate != DateTime.MaxValue) { field.MaxDate = rule.MaxDate; } } document.Fields.Add(member.Name, field); return(field); }
private void ReadEntity(TypeDocument typeDocument, Type type) { if (type == null || type.IsAutoClass || !IsLetter(type.Name[0]) || type.IsInterface || type.IsMarshalByRef || type.IsCOMObject || type == typeof(object) || type == typeof(void) || type == typeof(ValueType) || type == typeof(Type) || type == typeof(Enum) || type.Namespace == "System" || type.Namespace?.Contains("System.") == true) { return; } if (typeDocs.TryGetValue(type, out var doc)) { foreach (var field in doc.Fields) { if (typeDocument.Fields.ContainsKey(field.Key)) { typeDocument.Fields[field.Key] = field.Value; } else { typeDocument.Fields.Add(field.Key, field.Value); } } return; } if (typeDocs2.TryGetValue(type, out var _)) { ZeroTrace.WriteError("ReadEntity", "over flow", type.Name); return; } typeDocs2.Add(type, typeDocument); if (type.IsArray) { ReadEntity(typeDocument, type.Assembly.GetType(type.FullName.Split('[')[0])); return; } if (type.IsGenericType && !type.IsValueType && type.GetGenericTypeDefinition().GetInterface(typeof(IEnumerable <>).FullName) != null) { ReadEntity(typeDocument, type.GetGenericArguments().Last()); return; } XmlMember.Find(type); if (type.IsEnum) { foreach (var field in type.GetFields(BindingFlags.Static | BindingFlags.Public)) { if (field.IsSpecialName) { continue; } var info = CheckMember(typeDocument, type, field, field.FieldType, false, false, false); if (info != null) { info.TypeName = "int"; info.Example = ((int)field.GetValue(null)).ToString(); info.JsonName = null; } } typeDocs.Add(type, new TypeDocument { fields = typeDocument.fields?.ToDictionary(p => p.Key, p => p.Value) }); typeDocument.Copy(XmlMember.Find(type)); return; } var dc = type.GetAttribute <DataContractAttribute>(); var jo = type.GetAttribute <JsonObjectAttribute>(); foreach (var property in type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { if (property.IsSpecialName) { continue; } CheckMember(typeDocument, type, property, property.PropertyType, jo != null, dc != null); } foreach (var field in type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { if (!char.IsLetter(field.Name[0]) || field.IsSpecialName) { continue; } CheckMember(typeDocument, type, field, field.FieldType, jo != null, dc != null); } typeDocs.Add(type, new TypeDocument { fields = typeDocument.fields?.ToDictionary(p => p.Key, p => p.Value) }); typeDocument.Copy(XmlMember.Find(type)); }
public ZeroDiscover() { XmlMember.Load(GetType().Assembly); }
void CheckMember(TypeDocument document, Type parent, MemberInfo member, Type memType, bool json, bool dc) { if (!IsLetter(member.Name[0])) { return; } var field = new TypeDocument(); try { Type type = memType; if (memType.IsSubclassOf(typeof(IList <>))) { type = type.GetGenericArguments()[0]; } if (memType.IsSubclassOf(typeof(IDictionary <,>))) { type = type.GetGenericArguments()[1]; } if (memType.IsArray) { type = type.MakeArrayType(); } if (type.IsEnum) { field = ReadEntity(type, member.Name); field.ObjectType = ObjectType.Base; field.IsEnum = type.IsEnum; } else if (type.IsBaseType()) { field.ObjectType = ObjectType.Base; field.TypeName = ReflectionHelper.GetTypeName(type); } else { field = ReadEntity(type, member.Name); field.ObjectType = ObjectType.Object; } } catch { field.TypeName = "object"; } field.Copy(XmlMember.Find(parent, member.Name, member is PropertyInfo ? "P" : "F")); field.Name = field.JsonName = member.Name; field.ClassName = ReflectionHelper.GetTypeName(memType); if (json) { var ji = member.GetAttribute <JsonIgnoreAttribute>(); if (ji != null) { return; } var jp = member.GetAttribute <JsonPropertyAttribute>(); if (jp == null) { return; } if (!string.IsNullOrWhiteSpace(jp.PropertyName)) { field.JsonName = jp.PropertyName; } } else if (dc) { var id = member.GetAttribute <IgnoreDataMemberAttribute>(); if (id != null) { return; } var dm = member.GetAttribute <DataMemberAttribute>(); if (dm != null && !string.IsNullOrWhiteSpace(dm.Name)) { field.JsonName = dm.Name; } } if (memType.IsSubclassOf(typeof(IList <>))) { field.ObjectType = ObjectType.Array; } else if (memType.IsSubclassOf(typeof(IDictionary <,>))) { field.ObjectType = ObjectType.Dictionary; } else if (memType.IsArray) { field.ObjectType = ObjectType.Array; } var rule = member.GetAttribute <DataRuleAttribute>(); if (rule != null) { field.CanNull = rule.CanNull; field.Regex = rule.Regex; if (rule.Min != long.MinValue) { field.Min = rule.Min; } if (rule.Max != long.MinValue) { field.Max = rule.Max; } if (rule.MinDate != DateTime.MinValue) { field.MinDate = rule.MinDate; } if (rule.MaxDate != DateTime.MaxValue) { field.MaxDate = rule.MaxDate; } } document.Fields.Add(member.Name, field); }