public static void Main() { var referencedByDict = new Dictionary <Type, List <Type> >(); var referencesDict = new Dictionary <Type, List <Type> >(); var structureRefTypes = new Dictionary <Type, StructureReferenceType>(); var unsortedTypes = Assembly.GetExecutingAssembly().GetTypes() .Where(type => type.Namespace == "UpdateFieldCodeGenerator.Structures"); foreach (var type in unsortedTypes) { structureRefTypes[type] = StructureReferenceType.Root; } foreach (var type in unsortedTypes) { var allFields = type.GetFields(BindingFlags.Static | BindingFlags.Public) .Where(field => typeof(UpdateField).IsAssignableFrom(field.FieldType)) .Select(field => ResolveField(field).Field) .OrderBy(field => field.Order) .Select(field => GetFieldElementType(field.Type, StructureReferenceType.Embedded)) .Where(fieldType => fieldType.Item1.Namespace == "UpdateFieldCodeGenerator.Structures"); foreach (var(fieldType, refType) in allFields) { var reference = referencesDict.ComputeIfAbsent(type, k => new List <Type>()); if (!reference.Contains(fieldType)) { reference.Add(fieldType); } referencedByDict.ComputeIfAbsent(fieldType, k => new List <Type>()).Add(type); structureRefTypes[fieldType] = refType; } } foreach (var referencedBy in referencedByDict) { referencedBy.Value.Sort((a, b) => GetObjectType(a).CompareTo(GetObjectType(b))); } var typeList = structureRefTypes.Where(kvp => kvp.Value == StructureReferenceType.Root) .Select(kvp => kvp.Key) .OrderBy(type => GetObjectType(type)) .SelectMany(type => (referencesDict.ContainsKey(type) ? referencesDict[type] : Enumerable.Empty <Type>()).Concat(Enumerable.Repeat(type, 1))) .Distinct(); using (var handlers = new UpdateFieldHandlers()) { handlers.BeforeStructures(); foreach (var dataType in typeList) { var objectType = GetObjectType(referencedByDict.ContainsKey(dataType) ? referencedByDict[dataType].First() : dataType); WriteCreate(dataType, objectType, handlers); WriteUpdate(dataType, objectType, handlers); } handlers.AfterStructures(); } }
public static void Main() { var referencedByDict = new Dictionary <Type, List <Type> >(); var referencesDict = new Dictionary <Type, List <Type> >(); var structureRefTypes = new Dictionary <Type, StructureReferenceType>(); var unsortedTypes = Assembly.GetExecutingAssembly().GetTypes() .Where(type => type.Namespace == "UpdateFieldCodeGenerator.Structures") .ToList(); foreach (var type in unsortedTypes) { structureRefTypes[type] = StructureReferenceType.Root; } foreach (var type in unsortedTypes) { var allFields = type.GetFields(BindingFlags.Static | BindingFlags.Public) .Where(field => typeof(UpdateField).IsAssignableFrom(field.FieldType)) .Select(field => ResolveField(field).Field) .OrderBy(field => field.Order) .Select(field => GetFieldElementType(field.Type, StructureReferenceType.Embedded)) .Where(fieldType => fieldType.Item1.Namespace == "UpdateFieldCodeGenerator.Structures"); foreach (var(fieldType, refType) in allFields) { var reference = referencesDict.ComputeIfAbsent(type, k => new List <Type>()); if (!reference.Contains(fieldType)) { reference.Add(fieldType); } referencedByDict.ComputeIfAbsent(fieldType, k => new List <Type>()).Add(type); structureRefTypes[fieldType] = refType; } } var typeList = structureRefTypes.Where(kvp => kvp.Value == StructureReferenceType.Root) .Select(kvp => kvp.Key) .OrderBy(type => GetObjectType(type)) .ToList(); foreach (var type in typeList) { unsortedTypes.Remove(type); } // add all missed types while (unsortedTypes.Count > 0) { for (var i = 0; i < typeList.Count; ++i) { if (referencesDict.TryGetValue(typeList[i], out var referencedTypes)) { var insertIndex = i; foreach (var referencedType in referencedTypes) { var unsortedTypeIndex = unsortedTypes.IndexOf(referencedType); if (unsortedTypeIndex == -1) { continue; } typeList.Insert(insertIndex, referencedType); unsortedTypes.RemoveAt(unsortedTypeIndex); i = 0; break; } } } } if (unsortedTypes.Count > 0) { typeList.AddRange(unsortedTypes); } using (var handlers = new UpdateFieldHandlers()) { handlers.BeforeStructures(); foreach (var dataType in typeList) { var objectType = structureRefTypes[dataType] == StructureReferenceType.Root ? GetObjectType(dataType) : GetCommonObjectType(GetObjectTypeReferenceRoots(dataType, referencedByDict).Select(t => GetObjectType(t)).ToList()); WriteCreate(dataType, objectType, handlers); WriteUpdate(dataType, objectType, handlers); } handlers.AfterStructures(); } }