AutoMapper konfigurovat Třídy na dynamické

0

Otázka

Používáme AutoMapper importovat CSV soubory s dynamickou konfiguraci nastavit mapování. Používáme ExpandoObjects jako zdroj, a to funguje v pohodě.

Chtěl bych použít podobný přístup pro flexibilní export funkce. Nicméně, nemůžu najít způsob, jak konfigurovat dynamické mapování ze třídy typ dynamický. Díval jsem se na zdrojový kód zde , ale jak mohu poskytnout platný MapExpression pro dynamický typ za běhu?

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

Nejlepší odpověď

0

To se zdá být pracovní roztok - nahrazuje dynamický objekt třídy vytvořen za běhu. Vytvoření třídy typu na základě tohoto příspěvku:

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

V jiných jazycích

Tato stránka je v jiných jazycích

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