/// <summary> /// Create proxy type of specified type. /// </summary> /// <param name="moduleBuilder">Instance of <see cref="System.Reflection.Emit.ModuleBuilder"/>.</param> /// <param name="type">Type of interface to be implemented by the proxy type.</param> /// <returns>Generated proxy type that implements the specified interface.</returns> public static Type CreateProxyTypeOf(this ModuleBuilder moduleBuilder, Type type) { if (moduleBuilder is null) { throw new ArgumentNullException(nameof(moduleBuilder)); } if (type is null) { throw new ArgumentNullException(nameof(type)); } if (!type.IsInterface) { throw new InvalidOperationException(); } TypeBuilder typeBuilder = moduleBuilder.GetProxyTypeBuilder(type); typeBuilder.AddDefaultConstructor(); var interfaces = type.GetInterfaces(); // Properties are added as real getters and setters, // methods are added as dummy methods. var propertyInfos = type.GetProperties().Union(interfaces.SelectMany(i => i.GetProperties())).ToArray(); var properties = propertyInfos.ToDictionary(p => p.Name, p => p.PropertyType); // Filter methods which names starts with get_ or set_ to not add as methods because they are added as properties. MethodInfo[] methods = type.GetMethods().Union(interfaces.SelectMany(i => i.GetMethods())).ToArray(); var methodInfos = new List <MethodInfo>(methods.Length); foreach (var methodInfo in methods) { if (methodInfo.Name.StartsWith("get_", StringComparison.InvariantCulture) && methodInfo.GetParameters().Length == 0) { // This method is property getter. properties.TryAdd(methodInfo.Name.Substring("get_".Length), methodInfo.ReturnType); } else if (methodInfo.Name.StartsWith("set_", StringComparison.InvariantCulture) && methodInfo.GetParameters().Length == 1) { // This method is property setter. properties.TryAdd(methodInfo.Name.Substring("set_".Length), methodInfo.ReturnType); } else { // This does not look like property. methodInfos.Add(methodInfo); } } methodInfos.TrimExcess(); // Add properties. foreach (var property in properties) { typeBuilder.AddProperty(property.Key, property.Value, methods); } // Add methods. foreach (var methodInfo in methodInfos) { typeBuilder.AddDummyMethod(methodInfo); } return(typeBuilder.CreateType()); }