AutoMapper sınıfı dinamik olarak yapılandır

0

Soru

Eşlemeyi ayarlamak için dinamik yapılandırmaya sahip CSV dosyalarını içe aktarmak için AutoMapper kullanıyoruz. Kaynak olarak ExpandoObjects kullanıyoruz ve bu iyi çalışıyor.

Esnek bir dışa aktarma işlevi için benzer bir yaklaşım kullanmak istiyorum. Ancak, dinamik eşlemeyi bir sınıf türünden dinamiğe yapılandırmanın bir yolunu bulamıyorum. Buradaki kaynak koduna baktım, ancak çalışma zamanında dinamik bir tür için nasıl geçerli bir MapExpression sağlayabilirim?

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

En iyi cevabı

0

Bu çalışan bir çözüm gibi görünüyor - dinamik nesneyi çalışma zamanında oluşturulan bir sınıfla değiştirdi. Bu gönderiye dayalı sınıf türünün oluşturulması:

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

Diğer dillerde

Bu sayfa diğer dillerde

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