protected Type CreateProxyType(Type type) { if (type.GetConstructor(new Type[0]) == null) { throw new PatchProxyTypeException($"Type {type} doesn't have an empty constructor."); } RuntimeTypeBuilder proxyBuilder = new RuntimeTypeBuilder($"{{Guid.NewGuid()}}.{type.FullName}Patch", type); FieldBuilder modified = proxyBuilder.DefineField("_modified", typeof(HashSet <string>), FieldAttributes.Private); var modifiedField = Field(proxyBuilder.This, modified); foreach (PropertyInfo propInfo in type.GetRuntimeProperties()) { if (propInfo.CanRead && propInfo.CanWrite && propInfo.GetSetMethod().IsVirtual) { ParameterExpression valueExpr = Parameter(propInfo.PropertyType, "value"); var baseGet = Call(proxyBuilder.Base, propInfo.GetGetMethod()); proxyBuilder.OverrideMethod(propInfo.GetSetMethod(), new[] { valueExpr }, If(NotEqual(baseGet, valueExpr), Then( If(IsNull(modifiedField), Assign(modifiedField, New(typeof(HashSet <string>))) ), Call("Add", modifiedField, Constant(propInfo.Name)), Call(proxyBuilder.Base, propInfo.SetMethod, valueExpr) ) ) ); } } proxyBuilder.DefineMethod("Reset", null, Block( If(IsNotNull(modifiedField), Call("Clear", modifiedField) ) ) ); var propNameParam = Parameter(typeof(string), "propName"); proxyBuilder.DefineMethod("IsSet", new[] { propNameParam }, Block( Variable("result", Constant(false), out Expression result), If(IsNotNull(modifiedField), Assign(result, Call("Contains", modifiedField, propNameParam)) ), Result(result) ) ); proxyBuilder.AutoImplementInterface(typeof(IPatch)); return(proxyBuilder.Create()); }
public void auto_implement_interface() { RuntimeTypeBuilder typeBuilder = new RuntimeTypeBuilder("AutoImplenetInterface", typeof(BasePropertyClass)); typeBuilder.AutoImplementInterface(typeof(ITextProperty)); Type newType = typeBuilder.Create(); ITextProperty newInstance = (ITextProperty)Activator.CreateInstance(newType); newInstance.Text = "test text"; Assert.Equal("test text", newInstance.Text); }
public void define_autoproperty() { RuntimeTypeBuilder typeBuilder = new RuntimeTypeBuilder("DefineAutoProperty"); typeBuilder.DefineAutoProperty("TestProp", typeof(int)); Type newType = typeBuilder.Create(); object newInstance = Activator.CreateInstance(newType); PropertyInfo testPropInfo = newType.GetProperty("TestProp"); testPropInfo.SetValue(newInstance, 5); int result = (int)testPropInfo.GetValue(newInstance); Assert.Equal(5, result); }
public void call_base_method() { RuntimeTypeBuilder typeBuilder = new RuntimeTypeBuilder("CallBaseMethod", typeof(BaseMethodClass)); MethodInfo getTextInfo = typeof(BaseMethodClass).GetMethod("GetText"); typeBuilder.OverrideMethod(getTextInfo, null, Call("Concat", typeof(string), Call(typeBuilder.Base, getTextInfo), Constant(" (overriden)")) ); Type newType = typeBuilder.Create(); object newInstance = Activator.CreateInstance(newType); MethodInfo testMethodInfo = newType.GetMethod("GetText"); object result = testMethodInfo.Invoke(newInstance, null); Assert.Equal("this is the base class! (overriden)", result); }
public void override_property() { RuntimeTypeBuilder typeBuilder = new RuntimeTypeBuilder("OverrideProperty", typeof(BasePropertyClass)); PropertyInfo propInfo = typeof(BasePropertyClass).GetProperty("Text"); typeBuilder.OverrideMethod(propInfo.GetGetMethod(), null, Call("Concat", typeof(string), Call(typeBuilder.Base, propInfo.GetGetMethod()), Constant(" (overriden)")) ); Type newType = typeBuilder.Create(); object newInstance = Activator.CreateInstance(newType); propInfo.SetValue(newInstance, "this is a property!"); string result = (string)propInfo.GetValue(newInstance); Assert.Equal("this is a property! (overriden)", result); }
public void define_method() { RuntimeTypeBuilder typeBuilder = new RuntimeTypeBuilder("DefineMethod"); ParameterExpression a = Parameter(typeof(int), "a"); ParameterExpression b = Parameter(typeof(int), "b"); typeBuilder.DefineMethod("TestMethod", new[] { a, b }, Add(a, b) ); Type newType = typeBuilder.Create(); object newInstance = Activator.CreateInstance(newType); MethodInfo testMethodInfo = newType.GetMethod("TestMethod"); object result = testMethodInfo.Invoke(newInstance, new object[] { 5, 4 }); Assert.Equal(9, result); }
public void access_local_field() { RuntimeTypeBuilder typeBuilder = new RuntimeTypeBuilder("AccessLocalField"); ParameterExpression a = Parameter(typeof(int), "a"); ParameterExpression b = Parameter(typeof(int), "b"); var field = typeBuilder.DefineField("TestField", typeof(string)); typeBuilder.DefineMethod("TestMethod", null, Field(typeBuilder.This, field) ); Type newType = typeBuilder.Create(); object newInstance = Activator.CreateInstance(newType); FieldInfo fieldInfo = newType.GetField("TestField"); fieldInfo.SetValue(newInstance, "testValue"); MethodInfo testMethodInfo = newType.GetMethod("TestMethod"); object result = testMethodInfo.Invoke(newInstance, null); Assert.Equal("testValue", result); }