public virtual void Compile(ModuleBuilder builder) { if (_converter != null) { _converter.Compile(builder); } else { Type sourceType = SourceType; Type targetType = TargetMember.MemberType; _converter = _container.Converters.Get(sourceType, targetType); if (_converter == null && (_options & MemberMapOptions.Hierarchy) == MemberMapOptions.Hierarchy && !(TargetMember.MemberType.IsValueType && targetType == sourceType)) { var key = new TypeMapperKey(_container, sourceType, targetType); _genericMapperTypes.GetOrAdd(key, k => CreateMapper(builder, k.SourceType, k.TargetType)); } } }
public virtual void Emit(CompilationContext context) { Type sourceType = SourceType; Type targetType = TargetMember.MemberType; if (_converter != null) { EmitSource(context); _converter.Emit(sourceType, targetType, context); EmitSetTarget(context); return; } if ((_options & MemberMapOptions.Hierarchy) != MemberMapOptions.Hierarchy) { Action <CompilationContext> converter = GetConvertEmitter(sourceType, targetType); if (converter != null) { EmitSource(context); converter(context); EmitSetTarget(context); } } else { var key = new TypeMapperKey(_container, sourceType, targetType); Type mapperType = _genericMapperTypes[key]; if (targetType.IsClass && !targetType.IsNullable()) { LocalBuilder sourceValue = context.DeclareLocal(sourceType); EmitSource(context); context.Emit(OpCodes.Stloc, sourceValue); LocalBuilder targetValue = context.DeclareLocal(targetType); ((IMemberBuilder)TargetMember).EmitGetter(context); context.Emit(OpCodes.Stloc, targetValue); Label label = context.DefineLabel(); context.Emit(OpCodes.Ldloc, targetValue); context.Emit(OpCodes.Brtrue, label); context.Emit(OpCodes.Ldloc, sourceValue); context.CurrentType = sourceType; context.EmitCall(mapperType.GetMethod("Convert")); EmitSetTarget(context); Label finalLabel = context.DefineLabel(); context.Emit(OpCodes.Br, finalLabel); context.MakeLabel(label); context.Emit(OpCodes.Ldloc, sourceValue); context.Emit(OpCodes.Ldloc, targetValue); context.EmitCall(mapperType.GetMethod("Map")); context.MakeLabel(finalLabel); } else { EmitSource(context); context.CurrentType = sourceType; context.EmitCall(mapperType.GetMethod("Convert")); EmitSetTarget(context); } } }