private static void EmitComplexSetField(ILGenerator iL, FieldMappingInfo fieldMapping) { //call Map{Object|Array|List}(object source) iL.Emit(OpCodes.Call, listMethod.GetMapping(fieldMapping.SourceFieldType, fieldMapping.DestinationFieldType)); //set mapped value to destination field iL.Emit(OpCodes.Stfld, fieldMapping.DestinationField); }
private static void EmitComplexFieldMapping(ILGenerator iL, FieldMappingInfo fieldMapping, bool isClass) { if (fieldMapping.SourceFieldType.IsValueType) { //load destination object from variable EmitLoadDestinationObject(iL, isClass); //load source argument iL.Emit(OpCodes.Ldarg_0); //load field value from source iL.Emit(OpCodes.Ldfld, fieldMapping.SourceField); EmitComplexSetField(iL, fieldMapping); } else { Label label = iL.DefineLabel(); //load source argument iL.Emit(OpCodes.Ldarg_0); //load field value from source iL.Emit(OpCodes.Ldfld, fieldMapping.SourceField); //store field value in local variable at 1 position iL.Emit(OpCodes.Stloc_1); iL.Emit(OpCodes.Ldloc_1); //check if field value is not null iL.Emit(OpCodes.Brfalse_S, label); //load destination object from variable EmitLoadDestinationObject(iL, isClass); //load source field value from variable iL.Emit(OpCodes.Ldloc_1); EmitComplexSetField(iL, fieldMapping); //end if iL.MarkLabel(label); } }
private static bool LoadFields(Type sourceType, Type destinationType, List <FieldMappingInfo> fieldMappings) { var sourceFields = GetFields(sourceType); if (sourceFields.Count == 0) { return(false); } bool isComplexMapping = false; var bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public; while (destinationType != objectType) { var fields = destinationType.GetFields(bindingFlags); for (var i = fields.Length - 1; i > -1; i--) { var destinationField = fields[i]; sourceFields.TryGetValue(GetFieldNameHash(destinationField.Name), out var sourceField); if (sourceField != null) { var sourceFieldType = sourceField.FieldType; var destinationFieldType = destinationField.FieldType; var fieldMapping = new FieldMappingInfo() { SourceField = sourceField, DestinationField = destinationField }; if (sourceFieldType.IsEnum) { if (!(destinationFieldType.IsEnum || destinationFieldType == stringType || destinationFieldType == objectType || IsNullable(destinationFieldType))) { sourceFieldType = GetEnumType(sourceFieldType); } } else if (destinationFieldType.IsEnum && !(sourceFieldType == stringType || IsNullable(sourceFieldType))) { destinationFieldType = GetEnumType(destinationFieldType); } if (sourceFieldType == destinationFieldType) { fieldMapping.IsSimpleMapping = true; } else { fieldMapping.SourceFieldType = sourceFieldType; fieldMapping.DestinationFieldType = destinationFieldType; isComplexMapping = true; } fieldMappings.Add(fieldMapping); } } destinationType = destinationType.BaseType; bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic; } return(isComplexMapping); }
private static void EmitEnumFieldMapping(ILGenerator iL, FieldMappingInfo fieldMapping, bool isClass) { EmitLoadDestinationObject(iL, isClass); //load source from argument iL.Emit(OpCodes.Ldarg_0); //load parameters to MapEnumInternal method iL.Emit(OpCodes.Ldfld, fieldMapping.SourceField); iL.Emit(OpCodes.Ldc_I8, GetEnumMapping(fieldMapping.SourceFieldType, fieldMapping.DestinationFieldType)); //call MapEnumInternal iL.Emit(OpCodes.Call, mapEnumMethodInfo); //set mapped value to destination field iL.Emit(OpCodes.Stfld, fieldMapping.DestinationField); }
private static void EmitStringToEnumFieldMapping(ILGenerator iL, FieldMappingInfo fieldMapping, bool isClass) { //load destination from variable at 0 position EmitLoadDestinationObject(iL, isClass); //load source from argument iL.Emit(OpCodes.Ldarg_0); //load parameters to MapEnumInternal method iL.Emit(OpCodes.Ldfld, fieldMapping.SourceField); //call MapEnumInternal iL.Emit(OpCodes.Call, mapStringToEnumMethodInfo.MakeGenericMethod(fieldMapping.DestinationFieldType)); //set mapped value to destination field iL.Emit(OpCodes.Stfld, fieldMapping.DestinationField); }
private static void EmitStringFieldMapping(ILGenerator iL, FieldMappingInfo fieldMapping, bool isClass) { //load destination from variable at 0 position EmitLoadDestinationObject(iL, isClass); //load source from argument iL.Emit(OpCodes.Ldarg_0); //load parameters to MapEnumInternal method iL.Emit(OpCodes.Ldflda, fieldMapping.SourceField); iL.Emit(OpCodes.Constrained, fieldMapping.SourceFieldType); //call MapEnumInternal iL.Emit(OpCodes.Callvirt, objectType.GetMethod("ToString")); //set mapped value to destination field iL.Emit(OpCodes.Stfld, fieldMapping.DestinationField); }
private static void EmitSimpleFieldMapping(ILGenerator iL, FieldMappingInfo fieldMapping, bool isClass) { if (isClass) { iL.Emit(OpCodes.Ldloc_0); } else { iL.Emit(OpCodes.Ldloca_S, 0); } //load source reference iL.Emit(OpCodes.Ldarg_0); //copy source field to destination iL.Emit(OpCodes.Ldfld, fieldMapping.SourceField); iL.Emit(OpCodes.Stfld, fieldMapping.DestinationField); }
private static bool EmitPrimitiveFieldMapping(ILGenerator iL, FieldMappingInfo fieldMapping, bool isClass) { var mappingKey = GetMappingKey(fieldMapping.SourceFieldType, fieldMapping.DestinationFieldType); if (!primitiveTypeMappings.ContainsKey(mappingKey)) { return(false); } EmitLoadDestinationObject(iL, isClass); iL.Emit(OpCodes.Ldarg_0); iL.Emit(OpCodes.Ldfld, fieldMapping.SourceField); iL.Emit(OpCodes.Call, primitiveTypeMappings[mappingKey]); iL.Emit(OpCodes.Stfld, fieldMapping.DestinationField); return(true); }
private void CheckCircleReferences(Table table, TableMappingDefinition mappingDefinition) { if (_tablesToUpdateCircleReferences.ContainsKey(table.Name)) { _tablesToUpdateCircleReferences[table.Name].ForEach(r => { TableMappingDefinition temp = _tableMappingDefinitions.Single(d => d.DestinationTable.Name.Equals(r.OriginTableName)); FieldMappingDefinition fieldMappingDefinition = temp.FieldMappingDefinitions.SingleOrDefault(f => f.DestinationField.Name.Equals(r.OriginFieldName)); if(fieldMappingDefinition != null) { SourceTable sourceTable = temp.SourceTable; Field sourceField = fieldMappingDefinition.SourceField; DestinationTable destinationTable = temp.DestinationTable; Field destinationField = fieldMappingDefinition.DestinationField; FieldMappingInfo info = new FieldMappingInfo { DestinationField = destinationField, DestinationTable = destinationTable, SourceField = sourceField, SourceTable = sourceTable }; mappingDefinition.CircleReferences.Add(info); } }); } }