public void PocoTypeBuilder_AddPropertyAfterCreateType_ShouldThrowInvalidOperationException()
        {
            // Arrange
            PocoModuleBuilder pocoModuleBuilder = new PocoModuleBuilder();
            ModuleBuilder     moduleBuilder     = pocoModuleBuilder.ModuleBuilder;
            string            typeName          = "MyType";
            PocoTypeBuilder   pocoTypeBuilder   = new PocoTypeBuilder(moduleBuilder, typeName);

            string property1Name = "ID";
            Type   property1Type = typeof(int);

            string property2Name = "Name";
            Type   property2Type = typeof(string);

            // Act + Assert
            pocoTypeBuilder.AddProperty(property1Name, property1Type);
            var type = pocoTypeBuilder.CreateType();

            Assert.Throws <InvalidOperationException>(() =>
            {
                pocoTypeBuilder.AddProperty(property2Name, property2Type);
            });

            // Assert
            Assert.IsNotNull(type);
            Assert.IsTrue(type.IsClass);
            Assert.IsFalse(type.IsAbstract);
            Assert.IsFalse(type.IsSealed);
            Assert.IsFalse(type.IsGenericType);
            Assert.AreEqual(typeName, type.Name);

            Assert.AreEqual(1, type.GetProperties().Length);
            Assert.AreEqual(property1Name, type.GetProperties()[0].Name);
            Assert.AreEqual(property1Type, type.GetProperties()[0].PropertyType);
        }
        public void PocoTypeBuilder_CreateType_WithTwoProperties_ShouldReturnValidType()
        {
            // Arrange
            PocoModuleBuilder pocoModuleBuilder = new PocoModuleBuilder();
            ModuleBuilder     moduleBuilder     = pocoModuleBuilder.ModuleBuilder;
            string            typeName          = "MyType";
            PocoTypeBuilder   pocoTypeBuilder   = new PocoTypeBuilder(moduleBuilder, typeName);
            string            property1Name     = "ID";
            Type   property1Type = typeof(int);
            string property2Name = "Name";
            Type   property2Type = typeof(string);

            // Act
            pocoTypeBuilder.AddProperty(property1Name, property1Type);
            pocoTypeBuilder.AddProperty(property2Name, property2Type);
            var type = pocoTypeBuilder.CreateType();

            // Assert
            Assert.IsNotNull(type);
            Assert.IsTrue(type.IsClass);
            Assert.IsFalse(type.IsAbstract);
            Assert.IsFalse(type.IsSealed);
            Assert.IsFalse(type.IsGenericType);
            Assert.AreEqual(typeName, type.Name);
            Assert.AreEqual(2, type.GetProperties().Length);
            Assert.AreEqual(property1Name, type.GetProperties()[0].Name);
            Assert.AreEqual(property1Type, type.GetProperties()[0].PropertyType);
            Assert.AreEqual(property2Name, type.GetProperties()[1].Name);
            Assert.AreEqual(property2Type, type.GetProperties()[1].PropertyType);

            TestContext.WriteLine(type.Name);
            TestContext.WriteLine(type.FullName);
        }
        public void PocoInstanceBuilder_CreateInstance_WithNoParameters_ShouldReturnValidObject()
        {
            // Arrange
            PocoModuleBuilder pocoModuleBuilder = new PocoModuleBuilder();
            ModuleBuilder     moduleBuilder     = pocoModuleBuilder.ModuleBuilder;
            string            typeName          = "MyType";
            string            property1Name     = "ID";
            Type   property1Type = typeof(int);
            string property2Name = "Name";
            Type   property2Type = typeof(string);

            PocoTypeBuilder pocoTypeBuilder = new PocoTypeBuilder(moduleBuilder, typeName);

            pocoTypeBuilder.AddProperty(property1Name, property1Type);
            pocoTypeBuilder.AddProperty(property2Name, property2Type);

            Type type = pocoTypeBuilder.CreateType();
            PocoInstanceBuilder pocoInstanceBuilder = new PocoInstanceBuilder(type);

            // Act
            var instance = pocoInstanceBuilder.CreateInstance();

            // Assert
            Assert.IsNotNull(instance);

            TestContext.WriteLine($"{instance}");
        }
        public void PocoInstanceBuilder_CreateInstance_WithEmptyDictionaryWithReferentTypes_ShouldReturnValidObject()
        {
            // Arrange
            PocoModuleBuilder pocoModuleBuilder = new PocoModuleBuilder();
            ModuleBuilder     moduleBuilder     = pocoModuleBuilder.ModuleBuilder;
            string            typeName          = "MyType";

            string property1Name  = "ID";
            object property1Value = new { id = 1 };
            Type   property1Type  = property1Value.GetType();

            string property2Name  = "Name";
            object property2Value = new { name = "My Name" };
            Type   property2Type  = property2Value.GetType();

            PocoTypeBuilder pocoTypeBuilder = new PocoTypeBuilder(moduleBuilder, typeName);

            pocoTypeBuilder.AddProperty(property1Name, property1Type);
            pocoTypeBuilder.AddProperty(property2Name, property2Type);

            Type type = pocoTypeBuilder.CreateType();
            PocoInstanceBuilder pocoInstanceBuilder = new PocoInstanceBuilder(type);

            // Act
            var instance = pocoInstanceBuilder.CreateInstance(new Dictionary <string, object>());

            // Assert
            Assert.IsNotNull(instance);
            Assert.IsNull(pocoInstanceBuilder.GetValue(instance, property1Name));
            Assert.IsNull(pocoInstanceBuilder.GetValue(instance, property2Name));

            TestContext.WriteLine($"{instance}");
        }
        public Type CreateContextType(List <Table> tables)
        {
            Type        PocoType;
            TypeBuilder PocoTypeBuilder;

            //TypeBuilder ClassTypeBuilder;

            Types.Clear();
            TypeBuilders.Clear();

            //Context
            ContextTypeBuilder = DynamicTypeBuilder.GetTypeBuilder("Context", typeof(DbContextBase));

            //Context Constructor
            System.Reflection.Emit.ConstructorBuilder constructor = ContextTypeBuilder.DefineDefaultConstructor(System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.SpecialName | System.Reflection.MethodAttributes.RTSpecialName);

            //Create Normal Poco Type to be used as a reference
            foreach (Table table in tables)
            {
                TypeBuilders.Add(table.VariableName, CreatePocoTypeBuilder(table));
            }


            //Navigation properties
            foreach (Table table in tables)
            {
                CreateNavigationProperties(table);
            }


            //Creates DbSet Propeties for the Context
            foreach (Table ti in tables)
            {
                PocoTypeBuilder = TypeBuilders[ti.VariableName];
                PocoType        = PocoTypeBuilder.CreateType();
                Types.Add(ti.VariableName, PocoType);
                DynamicTypeBuilder.CreateProperty(ContextTypeBuilder, ti.VariableName, typeof(DbSet <>).MakeGenericType(new Type[] { PocoType }), false);
            }


            Type type = ContextTypeBuilder.CreateType();


            return(type);
        }
        public void PocoTypeBuilder_CreateType_WithNoProperties_ShouldReturnValidType()
        {
            // Arrange
            PocoModuleBuilder pocoModuleBuilder = new PocoModuleBuilder();
            ModuleBuilder     moduleBuilder     = pocoModuleBuilder.ModuleBuilder;
            string            typeName          = "MyType";
            PocoTypeBuilder   pocoTypeBuilder   = new PocoTypeBuilder(moduleBuilder, typeName);

            // Act
            var type = pocoTypeBuilder.CreateType();

            // Assert
            Assert.IsNotNull(type);
            Assert.IsTrue(type.IsClass);
            Assert.IsFalse(type.IsAbstract);
            Assert.IsFalse(type.IsSealed);
            Assert.IsFalse(type.IsGenericType);
            Assert.AreEqual(typeName, type.Name);

            TestContext.WriteLine(type.Name);
            TestContext.WriteLine(type.FullName);
        }
        public void PocoInstanceBuilder_CreateInstance_WithValidDictionary_ShouldReturnValidObject()
        {
            // Arrange
            PocoModuleBuilder pocoModuleBuilder = new PocoModuleBuilder();
            ModuleBuilder     moduleBuilder     = pocoModuleBuilder.ModuleBuilder;
            string            typeName          = "MyType";

            string property1Name  = "ID";
            Type   property1Type  = typeof(int);
            object property1Value = 1;

            string property2Name  = "Name";
            Type   property2Type  = typeof(string);
            object property2Value = "My Name";

            PocoTypeBuilder pocoTypeBuilder = new PocoTypeBuilder(moduleBuilder, typeName);

            pocoTypeBuilder.AddProperty(property1Name, property1Type);
            pocoTypeBuilder.AddProperty(property2Name, property2Type);

            Type type = pocoTypeBuilder.CreateType();
            PocoInstanceBuilder pocoInstanceBuilder = new PocoInstanceBuilder(type);

            // Act
            var instance = pocoInstanceBuilder.CreateInstance(new Dictionary <string, object>
            {
                { property2Name, property2Value },
                { property1Name, property1Value },
            });

            // Assert
            Assert.IsNotNull(instance);
            Assert.AreEqual(property1Value, pocoInstanceBuilder.GetValue(instance, property1Name));
            Assert.AreEqual(property2Value, pocoInstanceBuilder.GetValue(instance, property2Name));

            TestContext.WriteLine($"{instance}");
        }