Пример #1
0
        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();
            }
        }
Пример #2
0
        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();
            }
        }