예제 #1
0
 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));
         }
     }
 }
예제 #2
0
        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);
                }
            }
        }