private static Type CreateProxyType(Type type, string proxyTypeName) { var typeBuilder = DynamicModule.DefineType(proxyTypeName, TypeAttributes.Public, typeof(object)); // class Type$Proxy : IObjectProxy<Type> var objectProxyInterfaceType = typeof(IObjectProxy <>).MakeGenericType(type); typeBuilder.AddInterfaceImplementation(objectProxyInterfaceType); // class Type$Proxy : interfaces.. foreach (var interfaceType in type.GetInterfaces()) { typeBuilder.AddInterfaceImplementation(interfaceType); } // class > T _object var objectField = typeBuilder.DefineField("_object", type, FieldAttributes.Private | FieldAttributes.InitOnly); // class > IObjectProxy<T>.Object::get_Object var getObjectMethod = objectProxyInterfaceType.GetMethod("get_Object", publicInstance); var getObjectImplMethod = typeBuilder.DefineMethod( $"IObjectProxy<{type.FullName}>.get_Object", MethodAttributes.Private | MethodAttributes.Virtual, type, Type.EmptyTypes); // body > return _object; var il = getObjectImplMethod.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, objectField); il.Emit(OpCodes.Ret); typeBuilder.DefineMethodOverride(getObjectImplMethod, getObjectMethod); // class > .ctor var ctor = typeBuilder.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, new[] { type }); // body > _object = arg0 il = ctor.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Stfld, objectField); il.Emit(OpCodes.Ret); var typeInfo = type.GetTypeInfo(); DefineProxyProperties(typeBuilder, typeInfo, objectField); DefineProxyMethods(typeBuilder, typeInfo, objectField); return(typeBuilder.CreateType()); }
public static IObjectProxy <T> CreateProxy <T>(T obj) where T : class { var tType = typeof(T); if (tType == typeof(object)) { tType = obj.GetType(); } string typeName = $"{tType.FullName}$Proxy"; if (!DynamicModule.TryGetType(typeName, out var type)) { type = CreateProxyType(tType, typeName); } return((IObjectProxy <T>)Activator.CreateInstance(type, obj)); }