public static void CreateType(DynamicClass dynamicClass)
        {
            if (dynamicTypesByName.ContainsKey(dynamicClass.ObjectName))
            {
                throw new InvalidOperationException(string.Format("A type with the name {0} is already loaded. Either change the name of the type or alter it in the database and reinitialize the system", dynamicClass.ObjectName));
            }

            if (assemblyBuilder == null)
            {
                throw new InvalidOperationException("The assembly has not been initialized. Call InitializeDynamicClasses before creating new types.");
            }

            // Build the type using the given name and make it inherit from BaseObject
            TypeBuilder tb = moduleBuilder.DefineType(
                dynamicClass.ObjectName,
                TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout,
                typeof(BaseObject));

            // Build a default constructor for the type so that Newtonsoft knows how to handle it
            ConstructorBuilder constructor = tb.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);

            // go over each field on the class and create a property
            foreach (var field in dynamicClass.Fields)
            {
                // if the field is using a system type (or custom model coded in C#), use that
                if (field.PropertyType != null)
                {
                    CreateProperty(tb, field.PropertyName, field.PropertyType);
                }
                else
                {
                    // if the field is using a dynamic type, use that and throw exception if it doesn't exist
                    if (!string.IsNullOrEmpty(field.DynamicRuntimeType) && dynamicTypesByName.ContainsKey(field.DynamicRuntimeType))
                    {
                        CreateProperty(tb, field.PropertyName, dynamicTypesByName[field.DynamicRuntimeType]);
                    }
                    else
                    {
                        throw new ArgumentException(string.Format("No dynamic type exists by the name {0}", field.DynamicRuntimeType));
                    }
                }
            }

            // now that the properties are attached, create the type and cache it
            Type objectType = tb.CreateType();

            dynamicTypesByName[dynamicClass.ObjectName]   = objectType;
            settersByTypeNameAndProperty[objectType.Name] = PropertyWrapper.CreateFromTypeName(objectType.Name);
        }
        // takes a list of classes and sorts them so that all dependencies will be processed
        // first. Any cycles will cause an exception to be thrown
        public static List <DynamicClass> SortDependencyOrder(List <DynamicClass> dynamicClasses)
        {
            // Tarjan's algorithm for topological sorting to make sure dynamic classes
            // that depend on other dynamic classes are initialized first
            List <DynamicClass>         sortedDynamicClasses = new List <DynamicClass>();
            Dictionary <string, string> nodeStatus           = new Dictionary <string, string>();

            foreach (DynamicClass dynamicClass in dynamicClasses)
            {
                nodeStatus[dynamicClass.ObjectName] = UNMARKED;
            }

            while (nodeStatus.Values.Any(k => k == UNMARKED))
            {
                DynamicClass currentDynamicClass = dynamicClasses.First(dc => dc.ObjectName == nodeStatus.First(s => s.Value == UNMARKED).Key);
                Visit(currentDynamicClass, nodeStatus, dynamicClasses, sortedDynamicClasses);
            }

            return(sortedDynamicClasses);
        }
예제 #3
0
        static void Main(string[] args)
        {
            DynamicClass addressCLass = new DynamicClass()
            {
                ObjectName = "Address",
                Fields = new List<Field>()
                {
                    new Field() { PropertyName = "Address1", PropertyType = typeof(string) },
                    new Field() { PropertyName = "Address2", PropertyType = typeof(string) },
                    new Field() { PropertyName = "PostalCode", PropertyType = typeof(string) }
                }
            };

            DynamicClass dynamicClass = new DynamicClass()
            {
                ObjectName = "Person",
                Fields = new List<Field>()
                {
                    new Field() { PropertyName = "FirstName", PropertyType = typeof(string) },
                    new Field() { PropertyName = "LastName", PropertyType = typeof(string) },
                    new Field() { PropertyName = "Age", PropertyType = typeof(int) },
                    new Field() { PropertyName = "Address", DynamicRuntimeType = "Address" }
                }
            };

            DynamicClassInitializer.InitializeDynamicClasses(new List<DynamicClass>() { addressCLass, dynamicClass });

            Example1.Execute();
            Example2.Execute();
            Example3.Execute();
            Example3A.Execute();
            Example4.Execute();
            Example5.Execute();
            Example5A.Execute();
            Example6.Execute();
        }