/// <summary> /// Generates compile time codes /// </summary> /// <param name="stringBuilder"></param> /// <param name="assemblyLoader"></param> public static void GenerateCode(StringBuilder stringBuilder, AssemblyLoader assemblyLoader) { AllTypes.Clear(); foreach (var assembly in assemblyLoader.Assemblies) { foreach (var type in assembly.GetTypes()) { if (!AllTypes.Contains(type)) { AllTypes.Add(type); } foreach (var item in GetFullGenerics(type, assemblyLoader)) { if (!AllTypes.Contains(item)) { AllTypes.Add(item); } } } } foreach (var type in AllTypes) { GenerateModel(stringBuilder, type, assemblyLoader); } while (NeedToGenerateModels.Count > 0) { var item = NeedToGenerateModels.First(); GenerateModel(stringBuilder, item, assemblyLoader); NeedToGenerateModels.Remove(item); } }
static void GenerateClassModel(StringBuilder stringBuilder, Type type, AssemblyLoader assemblyLoader) { if (SkipToGenerateModels.Contains(type)) { return; } SkipToGenerateModels.Add(type); var properties = type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance).Where(x => x.CanWrite && x.CanRead).ToArray(); if (properties.Length == 0) { foreach (var method in type.GetMethods(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Static)) { if (!CanTakeType(method.ReturnType)) { continue; } if (!NeedToGenerateModels.Contains(method.ReturnType) && !SkipToGenerateModels.Contains(method.ReturnType)) { NeedToGenerateModels.Add(method.ReturnType); } foreach (var parameter in method.GetParameters()) { if (!NeedToGenerateModels.Contains(parameter.ParameterType) && !SkipToGenerateModels.Contains(parameter.ParameterType)) { NeedToGenerateModels.Add(parameter.ParameterType); } } } return; } stringBuilder.AppendLine(); stringBuilder.AppendLine($"TypeBuilder<{GetFriendlyTypeName(type)}>.Create().SerializeObject((serializer, builder, obj) =>"); stringBuilder.AppendLine("{"); stringBuilder.AppendLine("if (obj == null)"); stringBuilder.AppendLine("return;"); stringBuilder.AppendLine("if (serializer.SerializedObjects.TryGetValue(obj, out int index))"); stringBuilder.AppendLine("{"); stringBuilder.AppendLine(@"builder.Append(""\""{\""$ref\"":\"""");"); stringBuilder.AppendLine("builder.Append(index);"); stringBuilder.AppendLine(@"builder.Append(""\""}\"""");"); stringBuilder.AppendLine("}"); stringBuilder.AppendLine("else"); stringBuilder.AppendLine("{"); stringBuilder.AppendLine("serializer.ReferencedIndex++;"); stringBuilder.AppendLine("serializer.SerializedObjects[obj] = serializer.ReferencedIndex;"); stringBuilder.AppendLine(@"builder.Append(""\""{\""$id\"":\"""");"); stringBuilder.AppendLine("builder.Append(serializer.ReferencedIndex);"); foreach (var item in properties) { if (DirectTypes.Contains(item.PropertyType)) { stringBuilder.AppendLine($@"builder.Append(""\"",\""{item.Name}\"":\"""");"); stringBuilder.AppendLine($"builder.Append(obj.{item.Name});"); } else if (item.PropertyType.IsEnum) { stringBuilder.AppendLine($@"builder.Append(""\"",\""{item.Name}\"":\"""");"); stringBuilder.AppendLine($"builder.Append((int)obj.{item.Name});"); } else { if (!NeedToGenerateModels.Contains(item.PropertyType) && !SkipToGenerateModels.Contains(item.PropertyType)) { NeedToGenerateModels.Add(item.PropertyType); } stringBuilder.AppendLine($@"if (obj.{item.Name} != null)"); stringBuilder.AppendLine("{"); stringBuilder.AppendLine($@"builder.Append(""\"",\""{item.Name}\"":\"""");"); stringBuilder.AppendLine($"serializer.ContinueSerializeCompile(obj.{item.Name});"); stringBuilder.AppendLine("}"); } } stringBuilder.AppendLine("}"); stringBuilder.AppendLine("}).Build();"); }