Пример #1
0
        public Func <TSource, TTarget> CreateConverter(ModuleBuilder builder)
        {
            Initialize();
            var typeBuilder   = builder.DefineStaticType();
            var methodBuilder = typeBuilder.DefineStaticMethod("Map");

            methodBuilder.SetReturnType(typeof(TTarget));
            methodBuilder.SetParameters(typeof(TSource));
#if NetCore
            var reflectingTargetType = typeof(TTarget).GetTypeInfo();
            var reflectingSourceType = typeof(TSource).GetTypeInfo();
#else
            var reflectingTargetType = typeof(TTarget);
            var reflectingSourceType = typeof(TSource);
#endif

            var il      = methodBuilder.GetILGenerator();
            var context = new CompilationContext(il);
            if (reflectingSourceType.IsValueType)
            {
                context.SetSource(purpose =>
                {
                    if (purpose == LoadPurpose.MemberAccess)
                    {
                        il.Emit(OpCodes.Ldarga_S, 0);
                    }
                    else
                    {
                        il.Emit(OpCodes.Ldarg_0);
                    }
                });
            }
            else
            {
                context.SetSource(purpose => il.Emit(OpCodes.Ldarg_0));
            }
            var targetLocal = il.DeclareLocal(typeof(TTarget));
            _creator.Emit(context);
            il.Emit(OpCodes.Stloc, targetLocal);
            if (reflectingTargetType.IsValueType)
            {
                context.SetTarget(
                    purpose =>
                    il.Emit(purpose == LoadPurpose.MemberAccess ? OpCodes.Ldloca_S : OpCodes.Ldloc, targetLocal));
            }
            else
            {
                context.SetTarget(purpose => il.Emit(OpCodes.Ldloc, targetLocal));
            }
            EmitMap(context);
            context.LoadTarget(LoadPurpose.ReturnValue);
            context.Emit(OpCodes.Ret);
#if NetCore
            return((Func <TSource, TTarget>)typeBuilder.CreateTypeInfo().GetMethod("Map", BindingFlags.Static | BindingFlags.Public).CreateDelegate(typeof(Func <TSource, TTarget>)));
#else
            return((Func <TSource, TTarget>)Delegate.CreateDelegate(typeof(Func <TSource, TTarget>), typeBuilder.CreateType(), "Map"));
#endif
        }
Пример #2
0
        public Func <TSource, TTarget> CreateConverter(ModuleBuilder builder)
        {
            Initialize();
            TypeBuilder   typeBuilder   = builder.DefineStaticType();
            MethodBuilder methodBuilder = typeBuilder.DefineStaticMethod("Map");

            methodBuilder.SetReturnType(typeof(TTarget));
            methodBuilder.SetParameters(typeof(TSource));

            ILGenerator il      = methodBuilder.GetILGenerator();
            var         context = new CompilationContext(il);

            context.SetSource(() => il.Emit(OpCodes.Ldarg_0));
            LocalBuilder targetLocal = il.DeclareLocal(typeof(TTarget));

            _creator.Emit(context);
            il.Emit(OpCodes.Stloc, targetLocal);
            context.SetTarget(() => il.Emit(OpCodes.Ldloc, targetLocal));
            if (_customInvokerBuilder != null)
            {
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldloc, targetLocal);
                _customInvokerBuilder.Emit(context);
            }
            else
            {
                foreach (MemberMapper mapper in _memberMappers)
                {
                    mapper.Emit(context);
                }
            }
            context.LoadTarget();
            context.Emit(OpCodes.Ret);
            return
                ((Func <TSource, TTarget>)
                 Delegate.CreateDelegate(typeof(Func <TSource, TTarget>), typeBuilder.CreateType(), "Map"));
        }