public PropertyEmitter(TypeBuilder owner, PropertyDescription property) //, FieldBuilder propertyChangedField) { var name = property.Name; var propertyType = property.Type; pType = propertyType; _fieldBuilder = owner.DefineField($"<{name}>", propertyType, FieldAttributes.Private); _propertyBuilder = owner.DefineProperty(name, PropertyAttributes.None, propertyType, null); _getterBuilder = owner.DefineMethod($"get_{name}", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.SpecialName, propertyType, new Type[0]); BuildPropGetter(_getterBuilder, name, propertyType); _propertyBuilder.SetGetMethod(_getterBuilder); if (!property.CanWrite) { return; } _setterBuilder = owner.DefineMethod($"set_{name}", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.SpecialName, typeof(void), new[] { propertyType }); BuildPropSetter(_setterBuilder, name, propertyType); _propertyBuilder.SetSetMethod(_setterBuilder); CustomAttributeBuilder attributeBuilder = new AttributeEmitter().CreateAttributeBuilder(new WasEmittedAttribute(DateTime.Now.ToString())); _propertyBuilder.SetCustomAttribute(attributeBuilder); }
private Type EmitWrapper(TypeDescription typeDescription, IModuleBuilderInfo moduleBuilderInfo) { string name = BuildTypeName(typeDescription.TypeName, moduleBuilderInfo.AssemblyId); Type parentType = typeDescription.BaseType; Type[] typesToImplement = GetTypesToImplement(parentType); System.Diagnostics.Debug.WriteLine(name, $"Emitting new wrapper type: {name} based on: {parentType}."); TypeBuilder typeBuilder = moduleBuilderInfo.ModuleBuilder.DefineType ( name, TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.Public, parentType, typesToImplement ); CustomAttributeBuilder attributeBuilder = new AttributeEmitter().CreateAttributeBuilder(new WasEmittedAttribute(DateTime.Now.ToString())); typeBuilder.SetCustomAttribute(attributeBuilder); IEnumerable <ConstructorInfo> ctors = parentType.GetDeclaredConstructors(); BuildConstructors(typeBuilder, ctors); //// Build the Clone method. //override public object Clone() { return new <<ClassName>>(this); } ////MethodAttributes attributesForCloneMethod = MethodAttributes.Public | MethodAttributes.ReuseSlot | MethodAttributes.Virtual | MethodAttributes.HideBySig; //MethodAttributes attributesForCloneMethod = MethodAttributes.Public | MethodAttributes.HideBySig; //MethodBuilder mb = typeBuilder.DefineMethod("Clone", attributesForCloneMethod, typeof(object), new Type[0]); //BuildCloneMethod(mb); var propertiesToImplement = new List <PropertyDescription>(); // First we collect all properties, those with setters before getters in order to enable less specific redundant getters foreach (var property in typeDescription.PropertyDescriptions) { if (property.CanWrite) { propertiesToImplement.Insert(0, property); } else { propertiesToImplement.Add(property); } } var fieldBuilders = new Dictionary <string, PropertyEmitter>(); foreach (var property in propertiesToImplement) { if (fieldBuilders.TryGetValue(property.Name, out PropertyEmitter propertyEmitter)) { if ((propertyEmitter.PropertyType != property.Type) && ((property.CanWrite) || (!property.Type.IsAssignableFrom(propertyEmitter.PropertyType)))) { throw new ArgumentException( $"The interface has a conflicting property {property.Name}", nameof(parentType)); } } else { propertyEmitter = new PropertyEmitter(typeBuilder, property); //, propertyChangedField)); fieldBuilders.Add(property.Name, propertyEmitter); } } Type result = typeBuilder.CreateType(); return(result); }