AutoMapper configurer Classe dynamique

0

La question

Nous utilisons AutoMapper pour importer des fichiers CSV avec dynamique de configuration pour configurer le mappage. Nous utilisons ExpandoObjects comme source et cela fonctionne bien.

Je voudrais utiliser une approche similaire pour un flexible de la fonction d'exportation. Cependant, je ne peux pas trouver un moyen de configurer le mappage dynamique à partir d'une classe de type dynamique. J'ai regardé le code source ici, mais comment puis-je fournir une preuve de MapExpression pour un type dynamique au moment de l'exécution?

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

La meilleure réponse

0

Cela semble être une solution de travail - qui a remplacé la dynamique de l'objet par une classe créée au moment de l'exécution. Création de la classe à partir de ce 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

Dans d'autres langues

Cette page est dans d'autres langues

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