public TypeConstructor() { var interfaceType = typeof(IMetrics); var typeBuilder = ModuleBuilder.DefineType("GenericMetrics", TypeAttributes.Public | TypeAttributes.Sealed); typeBuilder.AddInterfaceImplementation(interfaceType); this.Properties = this.HandleProperties(typeBuilder, interfaceType); try { this.Type = typeBuilder.CreateTypeInfo().AsType(); } catch (TypeLoadException e) { throw new Exception($"Unable to create implementation for interface {interfaceType.FullName}", e); } }
private PropertyGrouping HandleProperties(TypeBuilder typeBuilder, Type interfaceType) { var grouping = new PropertyGrouping(InterfaceAndChildren(interfaceType, x => x.GetTypeInfo().GetProperties())); MethodAttributes attributes = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.SpecialName; foreach (var property in grouping.Metric) { var propertyBuilder = typeBuilder.DefineProperty(property.PropertyInfo.Name, PropertyAttributes.None, property.PropertyInfo.PropertyType, null); var getter = typeBuilder.DefineMethod(property.PropertyInfo.GetMethod.Name, attributes, property.PropertyInfo.PropertyType, new Type[0]); var backingField = typeBuilder.DefineField("bk_" + property.PropertyInfo.Name, property.PropertyInfo.PropertyType, FieldAttributes.Private); var getterIlGenerator = getter.GetILGenerator(); getterIlGenerator.Emit(OpCodes.Ldarg_0); getterIlGenerator.Emit(OpCodes.Ldfld, backingField); getterIlGenerator.Emit(OpCodes.Ret); propertyBuilder.SetGetMethod(getter); property.BackingField = backingField; } return(grouping); }