public void AddField_WithDefaultValue(Visibility visibility, Type fieldType, object defaultValue) { // generate the field name string fieldName = "m" + fieldType.Name; // setup code generation module CallbackCodeGenModule module = new CallbackCodeGenModule(); module.Declare = (m) => { MethodInfo genericMethod = typeof(CodeGenEngine) .GetMethods(BindingFlags.Public | BindingFlags.Instance) .Where(x => x.Name == "AddField" && x.IsGenericMethodDefinition && x.GetGenericArguments().Length == 1) .Where(x => x.GetParameters().Select(y => y.ParameterType).SequenceEqual(new[] { typeof(string), typeof(Visibility), x.GetGenericArguments()[0] })) .Single(); MethodInfo method = genericMethod.MakeGenericMethod(fieldType); method.Invoke(m.Engine, new object[] { fieldName, visibility, defaultValue }); }; // create the type ClassDefinition classDefinition = new ClassDefinition("MyClass"); classDefinition.AddModule(module); Type classType = CodeGenEngine.CreateClass(classDefinition); Assert.NotNull(classType); Assert.Equal(typeof(object), classType.BaseType); Assert.Equal("MyClass", classType.Name); // check whether the field was generated correctly var field = classType.GetField(fieldName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); Assert.NotNull(field); Assert.Equal(fieldType, field.FieldType); Assert.Equal(visibility, field.ToVisibility()); // instantiate the type dynamic obj = Activator.CreateInstance(classType); Assert.NotNull(obj); // check whether fields have a value of the expected type and default type var fieldValue = GetFieldValue(obj, fieldName); Assert.Equal(defaultValue, fieldValue); if (defaultValue != null) { // the type of the field must match the type of the default value Assert.IsType(defaultValue.GetType(), fieldValue); // if the field type is a reference type, the value must actually be the same... if (!fieldType.IsValueType) { Assert.Same(defaultValue, fieldValue); } } }
public void AddStaticField_WithInitializer(Visibility visibility, Type fieldType, object expectedValue, FieldInitializer initializer) { // generate the field name string fieldName = "s" + fieldType.Name; // setup code generation module CallbackCodeGenModule module = new CallbackCodeGenModule(); module.Declare = (m) => { MethodInfo genericMethod = typeof(CodeGenEngine) .GetMethods(BindingFlags.Public | BindingFlags.Instance) .Where(x => x.Name == "AddStaticField" && x.IsGenericMethodDefinition && x.GetGenericArguments().Length == 1) .Where(x => x.GetParameters().Select(y => y.ParameterType).SequenceEqual(new[] { typeof(string), typeof(Visibility), typeof(FieldInitializer) })) .Single(); MethodInfo method = genericMethod.MakeGenericMethod(fieldType); method.Invoke(m.Engine, new object[] { fieldName, visibility, initializer }); }; // create the type ClassDefinition classDefinition = new ClassDefinition("MyClass"); classDefinition.AddModule(module); Type classType = CodeGenEngine.CreateClass(classDefinition); Assert.NotNull(classType); Assert.Equal(typeof(object), classType.BaseType); Assert.Equal("MyClass", classType.Name); // check whether the field was generated correctly var field = classType.GetField(fieldName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); Assert.NotNull(field); Assert.Equal(fieldType, field.FieldType); Assert.Equal(visibility, field.ToVisibility()); // instantiate the type dynamic obj = Activator.CreateInstance(classType); Assert.NotNull(obj); // check whether fields have a value of the expected type and default type var fieldValue = GetStaticFieldValue(classType, fieldName); Assert.Equal(expectedValue, fieldValue); }
public void AddStaticField_WithFactoryMethod_Class(Visibility visibility) { // generate the field name string fieldName = "sField"; // setup code generation module CallbackCodeGenModule module = new CallbackCodeGenModule(); module.Declare = (m) => { m.Engine.AddStaticField <DemoClass>(fieldName, visibility, () => new DemoClass() { MyInt32 = 42, MyString = "Lorem Ipsum" }); }; // create the type ClassDefinition classDefinition = new ClassDefinition("MyClass"); classDefinition.AddModule(module); Type classType = CodeGenEngine.CreateClass(classDefinition); Assert.NotNull(classType); Assert.Equal(typeof(object), classType.BaseType); Assert.Equal("MyClass", classType.Name); // check whether the field was generated correctly var field = classType.GetField(fieldName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); Assert.NotNull(field); Assert.Equal(typeof(DemoClass), field.FieldType); Assert.Equal(visibility, field.ToVisibility()); // instantiate the type object obj = Activator.CreateInstance(classType); Assert.NotNull(obj); // check whether the field has the expected value var fieldValue = GetStaticFieldValue(classType, fieldName); Assert.NotNull(fieldValue); Assert.IsType <DemoClass>(fieldValue); Assert.Equal(42, ((DemoClass)fieldValue).MyInt32); Assert.Equal("Lorem Ipsum", ((DemoClass)fieldValue).MyString); }