/// <summary> /// Create the metadata attribute /// </summary> /// <param name="xmlStruct"></param> /// <param name="typeBuilder"></param> private void CreateRTMetadataAttribute(XmlStructLayoutRoot xmlStruct, TypeBuilder typeBuilder) { // Find MarshalAsAttribute's constructor by signature, then invoke var metadataType = typeof(MetadataHelpAttribute); var ctorInfo = metadataType.GetConstructor(Type.EmptyTypes); List<PropertyInfo> lstPropInfo = new List<PropertyInfo>(); List<object> lstPropValues = new List<object>(); if (string.IsNullOrEmpty(xmlStruct.Metadata.Description) == false) { lstPropInfo.Add(metadataType.GetProperty("Description")); lstPropValues.Add(xmlStruct.Metadata.Description); } if (string.IsNullOrEmpty(xmlStruct.Metadata.DisplayName) == false) { lstPropInfo.Add(metadataType.GetProperty("DisplayName")); lstPropValues.Add(xmlStruct.Metadata.DisplayName); } var fields = metadataType.GetFields(BindingFlags.Public | BindingFlags.Instance); var marshalAsAttr = new CustomAttributeBuilder(ctorInfo, new object[] { }, lstPropInfo.ToArray(), lstPropValues.ToArray()); typeBuilder.SetCustomAttribute(marshalAsAttr); }
/// <summary> /// Runtime struct type builder /// </summary> /// <param name="moduleBuilder"></param> /// <param name="xmlNamespace"></param> /// <param name="xmlStruct"></param> /// <returns></returns> private TypeBuilder CreateRTStructType(ModuleBuilder moduleBuilder, XmlModelNamespaceRoot xmlNamespace, XmlStructLayoutRoot xmlStruct) { TypeBuilder typeBuilder = moduleBuilder.DefineType(string.Format("{0}.{1}", xmlNamespace.Namespace, xmlStruct.Name), TypeAttributes.Public | TypeAttributes.SequentialLayout | TypeAttributes.Serializable | TypeAttributes.AnsiClass, typeof(ValueType), xmlStruct.Pack); if (xmlStruct.Metadata != null) { CreateRTMetadataAttribute(xmlStruct, typeBuilder); } // Foreach field foreach (XmlStructFieldLayout xmlField in xmlStruct.Fields) { FieldBuilder fieldBuilder = CreateRTFieldType(typeBuilder, xmlStruct, xmlField); } return typeBuilder; }
/// <summary> /// Create field /// </summary> /// <param name="typeBuilder"></param> /// <param name="xmlStruct"></param> /// <param name="xmlField"></param> /// <returns></returns> private FieldBuilder CreateRTFieldType(TypeBuilder typeBuilder, XmlStructLayoutRoot xmlStruct, XmlStructFieldLayout xmlField) { Type fieldType = null; if (xmlField.NetType != TypeCode.Empty) fieldType = FactoryStandardType.Get(xmlField.NetType); if (string.IsNullOrEmpty(xmlField.RefType) == false) { // Find the type from current assembly fieldType = RTAssemblyBuilder.GetType(xmlField.RefType, true); } if (xmlField.IsArray) fieldType = fieldType.MakeArrayType(); FieldBuilder fieldBuilder = typeBuilder.DefineField( xmlField.Name, fieldType, FieldAttributes.Public); if (xmlField.CanMarshallAsStaticSize == true) { CreateRTMarshalAsAttribute(xmlField, fieldBuilder); } if(xmlField.Metadata != null) { CreateRTMetadataAttribute(xmlField, fieldBuilder); } return fieldBuilder; }