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); }
public Type GetOrAdd(TypeDescription td) { return(_emittedTypes.GetOrAdd(td)); }
public Type EmitWrapperType(TypeDescription td) { return(EmitWrapper(td, _mbInfo)); }