AutoMapper configurar Clase dinámica

0

Pregunta

Utilizamos AutoMapper para la importación de archivos CSV con la dinámica de configuración para configurar la asignación. Utilizamos ExpandoObjects como fuente y este funciona bien.

Me gustaría utilizar un enfoque similar para una flexible de la función de exportación. Sin embargo, no puedo encontrar una manera para configurar la asignación dinámica de una clase de tipo dinámico. He mirado el código fuente aquí , pero ¿cómo puedo proporcionar una válida MapExpression para una dinámica de tipo en tiempo de ejecución?

automapper c# dynamic
2021-11-23 11:17:53
1

Mejor respuesta

0

Esto parece ser una solución de trabajo: se reemplaza el objeto dinámico por una clase creada en tiempo de ejecución. La creación de la clase el tipo basada en este post:

using AutoMapper;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using System.Threading;

namespace AutoMapperDynamicDest
{

    public class Bar
    {
        public string Bar1 { get; set; }
        public string Bar2 { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // create a new class type - property definition should come from a configuration file 
            var myDynamicType = CreateMyType(new (string PropName, Type PropType)[] { ("Foo1", typeof(string)), ("Foo2", typeof(string)) });

            var config = new MapperConfiguration(cfg => cfg.CreateMap(typeof(Bar), myDynamicType)
                .ForAllMembers(o =>
                {
                    // again, this should come from a configuration file 
                    switch(o.DestinationMember.Name)
                    {
                        case "Foo1":
                            //o.MapFrom(s => ((Bar)s).Bar1);
                            o.MapFrom("Bar1");
                            break;
                        default:
                            o.Ignore();
                            break;
                    }
                }));


            // Remove in production - test only 
            config.AssertConfigurationIsValid();
            var mapper = config.CreateMapper();

            // This is the data object to be exported 
            var bar = new Bar();
            bar.Bar1 = "This should be mapped to Foo1";

            // Map the data object to a new object of dynamic type
            dynamic res = mapper.Map(bar, typeof(Bar), myDynamicType);

            if (res.Foo1 != "This should be mapped to Foo1")
            {
                Console.WriteLine("Map did not succeed");
            }
            else
            {
                Console.WriteLine("Mapped successfully from Bar.Bar1 to dynamic.Foo1");
            }

            Console.ReadKey();

        }

        /// <summary>
        /// Creates a class type with properties on the fly
        /// </summary>
        public static Type CreateMyType(IEnumerable<(string PropName, Type PropType)> properties)
        {
            AssemblyBuilder assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(
                 new AssemblyName(Guid.NewGuid().ToString()), AssemblyBuilderAccess.Run);

            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("ModuleName");
            TypeBuilder typeBuilder = moduleBuilder.DefineType(
                  "MyNamespace.TypeName", TypeAttributes.Public | TypeAttributes.Class);

            typeBuilder.DefineDefaultConstructor(MethodAttributes.Public);

            foreach (var prop in properties)
            {
                CreateProperty(typeBuilder, prop.PropName, prop.PropType);
            }

            // Create the type itself
            Type newType = typeBuilder.CreateType();

            return newType;
        }


        public static void CreateProperty(TypeBuilder tb, string propertyName, Type propertyType)
        {
            FieldBuilder fieldBuilder = tb.DefineField("_" + propertyName, propertyType, FieldAttributes.Private);

            PropertyBuilder propertyBuilder = tb.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null);
            MethodBuilder getPropMthdBldr = tb.DefineMethod("get_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, propertyType, Type.EmptyTypes);
            ILGenerator getIl = getPropMthdBldr.GetILGenerator();

            getIl.Emit(OpCodes.Ldarg_0);
            getIl.Emit(OpCodes.Ldfld, fieldBuilder);
            getIl.Emit(OpCodes.Ret);

            MethodBuilder setPropMthdBldr =
                tb.DefineMethod("set_" + propertyName,
                  MethodAttributes.Public |
                  MethodAttributes.SpecialName |
                  MethodAttributes.HideBySig,
                  null, new[] { propertyType });

            ILGenerator setIl = setPropMthdBldr.GetILGenerator();
            Label modifyProperty = setIl.DefineLabel();
            Label exitSet = setIl.DefineLabel();

            setIl.MarkLabel(modifyProperty);
            setIl.Emit(OpCodes.Ldarg_0);
            setIl.Emit(OpCodes.Ldarg_1);
            setIl.Emit(OpCodes.Stfld, fieldBuilder);

            setIl.Emit(OpCodes.Nop);
            setIl.MarkLabel(exitSet);
            setIl.Emit(OpCodes.Ret);

            propertyBuilder.SetGetMethod(getPropMthdBldr);
            propertyBuilder.SetSetMethod(setPropMthdBldr);
        }
    }

}
2021-11-24 08:41:37

En otros idiomas

Esta página está en otros idiomas

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Slovenský
..................................................................................................................