public MetadataTypes GetMetadataTypes(IRequest req) { var metadata = new MetadataTypes { Config = config, }; var skipTypes = config.IgnoreTypes ?? new HashSet <Type>(); var opTypes = new HashSet <Type>(); var ignoreNamespaces = config.IgnoreTypesInNamespaces ?? new List <string>(); var exportTypes = config.ExportTypes ?? new HashSet <Type>(); foreach (var operation in meta.Operations) { if (!meta.IsVisible(req, operation)) { continue; } if (opTypes.Contains(operation.RequestType)) { continue; } if (skipTypes.Contains(operation.RequestType)) { continue; } if (ignoreNamespaces.Contains(operation.RequestType.Namespace)) { continue; } var opType = new MetadataOperationType { Actions = operation.Actions, Request = ToType(operation.RequestType), Response = ToType(operation.ResponseType), }; metadata.Operations.Add(opType); opTypes.Add(operation.RequestType); if (operation.ResponseType != null) { if (skipTypes.Contains(operation.ResponseType)) { //Config.IgnoreTypesInNamespaces in CSharpGenerator opType.Response = null; } else { opTypes.Add(operation.ResponseType); } } } var considered = new HashSet <Type>(opTypes); var queue = new Queue <Type>(opTypes); Func <Type, bool> ignoreTypeFn = t => t == null || t.IsGenericParameter || t == typeof(Enum) || considered.Contains(t) || skipTypes.Contains(t) || (ignoreNamespaces.Contains(t.Namespace) && !exportTypes.Contains(t)); Action <Type> registerTypeFn = null; registerTypeFn = t => { if (t.IsArray || t == typeof(Array)) { return; } considered.Add(t); queue.Enqueue(t); if ((!t.IsSystemType() && (t.IsClass || t.IsEnum || t.IsInterface) && !(t.IsGenericParameter)) || exportTypes.Contains(t)) { metadata.Types.Add(ToType(t)); foreach (var ns in GetNamespacesUsed(t)) { if (!metadata.Namespaces.Contains(ns)) { metadata.Namespaces.Add(ns); } } } }; while (queue.Count > 0) { var type = queue.Dequeue(); if (IsSystemCollection(type)) { type = type.GetCollectionType(); if (type != null && !ignoreTypeFn(type)) { registerTypeFn(type); } continue; } if (type.DeclaringType != null) { if (!ignoreTypeFn(type.DeclaringType)) { registerTypeFn(type.DeclaringType); } } if (type.HasInterface(typeof(IService)) && type.GetNestedTypes().IsEmpty()) { continue; } if (!type.IsUserType() && !type.IsInterface && !exportTypes.Contains(type)) { continue; } if (!type.HasInterface(typeof(IService))) { foreach (var pi in type.GetSerializableProperties() .Where(pi => !ignoreTypeFn(pi.PropertyType))) { registerTypeFn(pi.PropertyType); //Register Property Array Element Types if (pi.PropertyType.IsArray && !ignoreTypeFn(pi.PropertyType.GetElementType())) { registerTypeFn(pi.PropertyType.GetElementType()); } //Register Property Generic Arg Types if (!pi.PropertyType.IsGenericType()) { continue; } var propArgs = pi.PropertyType.GetGenericArguments(); foreach (var arg in propArgs.Where(arg => !ignoreTypeFn(arg))) { registerTypeFn(arg); } } } var genericBaseTypeDef = type.BaseType != null && type.BaseType.IsGenericType ? type.BaseType.GetGenericTypeDefinition() : null; if (!ignoreTypeFn(type.BaseType) || genericBaseTypeDef == typeof(QueryBase <,>)) { if (genericBaseTypeDef != null) { if (!ignoreTypeFn(genericBaseTypeDef)) { registerTypeFn(genericBaseTypeDef); } foreach (var arg in type.BaseType.GetGenericArguments() .Where(arg => !ignoreTypeFn(arg))) { registerTypeFn(arg); } } else { registerTypeFn(type.BaseType); } } if (!type.IsGenericType()) { continue; } //Register Generic Arg Types var args = type.GetGenericArguments(); foreach (var arg in args.Where(arg => !ignoreTypeFn(arg))) { registerTypeFn(arg); } } return(metadata); }
public MetadataTypes GetMetadataTypes(IRequest req) { var metadata = new MetadataTypes { Config = config, }; var skipTypes = config.IgnoreTypes ?? new HashSet <Type>(); var opTypes = new HashSet <Type>(); var ignoreNamespaces = config.IgnoreTypesInNamespaces ?? new List <string>(); foreach (var operation in meta.Operations) { if (!meta.IsVisible(req, operation)) { continue; } if (opTypes.Contains(operation.RequestType)) { continue; } if (skipTypes.Contains(operation.RequestType)) { continue; } if (ignoreNamespaces.Contains(operation.RequestType.Namespace)) { continue; } var opType = new MetadataOperationType { Actions = operation.Actions, Request = ToType(operation.RequestType), Response = ToType(operation.ResponseType), }; metadata.Operations.Add(opType); opTypes.Add(operation.RequestType); if (operation.ResponseType != null) { if (skipTypes.Contains(operation.ResponseType)) { //Config.IgnoreTypesInNamespaces in CSharpGenerator opType.Response = null; } else { opTypes.Add(operation.ResponseType); } } } foreach (var type in meta.GetAllTypes()) { if (opTypes.Contains(type)) { continue; } if (skipTypes.Contains(type)) { continue; } if (ignoreNamespaces.Contains(type.Namespace)) { continue; } metadata.Operations.Add(new MetadataOperationType { Request = ToType(type), }); opTypes.Add(type); } var considered = new HashSet <Type>(opTypes); var queue = new Queue <Type>(opTypes); Func <Type, bool> ignoreTypeFn = t => t == null || considered.Contains(t) || skipTypes.Contains(t) || ignoreNamespaces.Contains(t.Namespace); Action <Type> registerTypeFn = t => { considered.Add(t); queue.Enqueue(t); if (t.IsUserType()) { metadata.Types.Add(ToType(t)); } }; while (queue.Count > 0) { var type = queue.Dequeue(); foreach (var pi in type.GetSerializableProperties() .Where(pi => !ignoreTypeFn(pi.PropertyType))) { registerTypeFn(pi.PropertyType); } if (!ignoreTypeFn(type.BaseType)) { registerTypeFn(type.BaseType); } if (!type.IsGenericType()) { continue; } var args = type.GetGenericArguments(); foreach (var arg in args.Where(arg => !ignoreTypeFn(arg))) { registerTypeFn(arg); } } return(metadata); }