public void AddEvents_UsingBuiltinImplementation_Standard() { // create the type ClassDefinition classDefinition = new ClassDefinition("MyClass"); classDefinition.AddModule(new TestModule_AddEvent_UsingBuiltinImplementation_Standard()); Type classType = CodeGenEngine.CreateClass(classDefinition); Assert.NotNull(classType); Assert.Equal(typeof(object), classType.BaseType); Assert.Equal("MyClass", classType.Name); // instantiate the type dynamic obj = Activator.CreateInstance(classType); Assert.NotNull(obj); // event type: System.EventHandler EventHandler handler1 = (sender, e) => { Assert.Same(obj, sender); Assert.Same(EventArgs.Empty, e); }; obj.NonGeneric += handler1; obj.OnNonGeneric(); obj.NonGeneric -= handler1; // event type: System.EventHandler<T> with T == System.EventArgs EventHandler <EventArgs> handler2 = (sender, e) => { Assert.Same(obj, sender); Assert.Same(EventArgs.Empty, e); }; obj.GenericBasic += handler2; obj.OnGenericBasic(); obj.GenericBasic -= handler2; // event type: System.EventHandler<T> with T derived from System.EventArgs SpecializedEventArgs e3 = new SpecializedEventArgs(); EventHandler <SpecializedEventArgs> handler3 = (sender, e) => { Assert.Same(obj, sender); Assert.Same(e3, e); }; obj.GenericSpecialized += handler3; obj.OnGenericSpecialized(e3); obj.GenericSpecialized -= handler3; // event type: custom delegate type SpecialDelegateEventHandler handler4 = (s, x) => { Assert.Equal("test", s); Assert.Equal(42, x); }; obj.Special += handler4; obj.OnSpecial("test", 42); obj.Special -= handler4; }
[InlineData(null)] // random class name public void GenerateEmptyClass_DerivedFromClassWithoutParameterlessConstructor(string className) { Assert.Throws <CodeGenException>(() => { // should throw an exception, because the base class does not have a parameterless constructor ClassDefinition classDefinition = new ClassDefinition(typeof(ClassWithoutParameterlessConstructor), false, className); CodeGenEngine.CreateClass(classDefinition); }); }
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 GetAbstractProperties() { // create the type ClassDefinition classDefinition = new ClassDefinition(typeof(GetAbstractPropertiesClassC), false, "MyClass"); classDefinition.AddModule(new TestModule_GetAbstractProperties()); Type classType = CodeGenEngine.CreateClass(classDefinition); Assert.NotNull(classType); Assert.Equal(typeof(GetAbstractPropertiesClassC), classType.BaseType); Assert.Equal("MyClass", classType.Name); }
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); }
[InlineData(null, true)] // random class name, create pass-through constructors public void GenerateEmptyClass_DerivedFromClassWithParameterlessConstructor(string className, bool createPassThroughConstructors) { // create the type ClassDefinition classDefinition = new ClassDefinition(typeof(ClassWithParameterlessConstructor), createPassThroughConstructors, "MyClass"); Type classType = CodeGenEngine.CreateClass(classDefinition); Assert.NotNull(classType); Assert.Equal(typeof(ClassWithParameterlessConstructor), classType.BaseType); if (className != null) { Assert.Equal(className, classType.Name); } // instantiate the type dynamic obj = Activator.CreateInstance(classType); Assert.NotNull(obj); }
[InlineData(null)] // random class name public void GenerateEmptyClass(string className) { // create the type ClassDefinition classDefinition = new ClassDefinition(className); Type classType = CodeGenEngine.CreateClass(classDefinition); Assert.NotNull(classType); Assert.Equal(typeof(object), classType.BaseType); if (className != null) { Assert.Equal(className, classType.Name); } // instantiate the type dynamic obj = Activator.CreateInstance(classType); Assert.NotNull(obj); }
public void AddStaticEvent_UsingBuiltinImplementation_Standard() { // create the type ClassDefinition classDefinition = new ClassDefinition("MyClass"); classDefinition.AddModule(new TestModule_AddStaticEvent_UsingBuiltinImplementation_Standard()); Type classType = CodeGenEngine.CreateClass(classDefinition); Assert.NotNull(classType); Assert.Equal(typeof(object), classType.BaseType); Assert.Equal("MyClass", classType.Name); // event type: System.EventHandler // ---------------------------------------------------------------------------------- EventHandler handler1 = (sender, e) => { Assert.Null(sender); Assert.Same(EventArgs.Empty, e); }; EventInfo eventInfo1 = classType.GetEvent("NonGeneric"); eventInfo1.AddEventHandler(null, handler1); MethodInfo eventRaiser1 = classType.GetMethod("OnNonGeneric"); eventRaiser1.Invoke(null, Type.EmptyTypes); eventInfo1.RemoveEventHandler(null, handler1); // event type: System.EventHandler<T> with T == System.EventArgs // ---------------------------------------------------------------------------------- EventHandler <EventArgs> handler2 = (sender, e) => { Assert.Null(sender); Assert.Same(EventArgs.Empty, e); }; EventInfo eventInfo2 = classType.GetEvent("GenericBasic"); eventInfo2.AddEventHandler(null, handler2); MethodInfo eventRaiser2 = classType.GetMethod("OnGenericBasic"); eventRaiser2.Invoke(null, Type.EmptyTypes); eventInfo2.RemoveEventHandler(null, handler2); // event type: System.EventHandler<T> with T derived from System.EventArgs // ---------------------------------------------------------------------------------- SpecializedEventArgs e3 = new SpecializedEventArgs(); EventHandler <SpecializedEventArgs> handler3 = (sender, e) => { Assert.Null(sender); Assert.Same(e3, e); }; EventInfo eventInfo3 = classType.GetEvent("GenericSpecialized"); eventInfo3.AddEventHandler(null, handler3); MethodInfo eventRaiser3 = classType.GetMethod("OnGenericSpecialized"); eventRaiser3.Invoke(null, new object[] { e3 }); eventInfo3.RemoveEventHandler(null, handler3); // event type: custom delegate type // ---------------------------------------------------------------------------------- SpecialDelegateEventHandler handler4 = (s, x) => { Assert.Equal("test", s); Assert.Equal(42, x); }; EventInfo eventInfo4 = classType.GetEvent("Special"); eventInfo4.AddEventHandler(null, handler4); MethodInfo eventRaiser4 = classType.GetMethod("OnSpecial"); eventRaiser4.Invoke(null, new object[] { "test", 42 }); eventInfo4.RemoveEventHandler(null, handler4); }