public static Type MakeType()

in src/Epam.GraphQL/Extensions/DictionaryExtensions.cs [37:106]


        public static Type MakeType(this IDictionary<string, Type> properties, string typeName, Type? parent = null)
        {
            Guards.ThrowIfNullOrEmpty(typeName, nameof(typeName));

            return _typeCache.GetOrAdd((parent, typeName, properties), key =>
            {
                Interlocked.Increment(ref _typeCacheCount);

                var (baseType, name, props) = key;
                var baseTypeName = baseType == null || baseType == typeof(object) ? string.Empty : baseType.Name;
                var baseTypeIsInterface = baseType != null && baseType.IsInterface;

                var tb = ILUtils.DefineType($"<{baseTypeName}>__{name}`{_typeCacheCount}", baseTypeIsInterface ? null : baseType);

                var propertyList = new List<PropertyBuilder>();

                if (baseTypeIsInterface)
                {
                    tb.AddInterfaceImplementation(baseType!);

                    foreach (var prop in baseType!.GetProperties())
                    {
                        var backingField = tb.DefineBackingField(prop.Name, prop.PropertyType);
                        propertyList.Add(tb.DefineProperty(backingField, prop.Name));
                    }

                    foreach (var baseInterface in baseType.GetInterfaces())
                    {
                        foreach (var prop in baseInterface.GetProperties())
                        {
                            var backingField = tb.DefineBackingField(prop.Name, prop.PropertyType);
                            propertyList.Add(tb.DefineProperty(backingField, prop.Name)); // TODO Check if baseInterface should be passed to DefineProperty for interfaces
                        }
                    }

                    foreach (var method in baseType.GetMethods().Concat(baseType.GetInterfaces().SelectMany(t => t.GetMethods())).Where(m => !m.IsSpecialName && m.IsAbstract))
                    {
                        tb.DefineNotImplementedMethodOverride(method);
                    }
                }
                else if (baseType != null)
                {
                    foreach (var prop in baseType.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => !p.CanWrite))
                    {
                        var backingField = tb.DefineBackingField(prop.Name, prop.PropertyType);
                        propertyList.Add(tb.DefineProperty(backingField, prop.Name));
                    }
                }

                tb.MakeCompilerGenerated();

                foreach (var field in props)
                {
                    var backingField = tb.DefineBackingField(field.Key, field.Value);
                    propertyList.Add(tb.DefineProperty(backingField, field.Key));
                }

                tb.SetDebuggerDisplayProperties(props.Select(p => p.Key));
                tb.DefineEqualsByPublicPropertiesMethod(propertyList);
                tb.DefineGetHashCodeByPublicPropertiesMethod(propertyList);
                tb.DefineToStringByPublicPropertiesMethod(propertyList);

                var objectType = tb.CreateTypeInfo();

                // According to its signature, tb.CreateTypeInfo() can return null
                Guards.ThrowNotSupportedIf(objectType == null);

                return objectType!;
            });
        }