【问题标题】:C# Creating AutoMapper mapping using reflectionC# 使用反射创建 AutoMapper 映射
【发布时间】:2017-03-13 16:22:54
【问题描述】:

我需要创建一个映射(使用 AutoMapper),从所有从一个抽象类派生的 n 个类到一个契约类

例如:

public abstract class bar
{
   public string Field1 {get; set;}       
   public someClass Field2 {get; set;}
}

public class foo1bar: bar
{
 // members
}

public class foo2bar: bar
{
 // members
}

public class barContract
{
  public string Field1 {get; set;}

  // this will use existing someClass.Description field
  public string Field2Description {get; set;} 
}

bar 类的实现是多种的,并且也可能会改变(更多将被添加)。由于 Automapper 无法映射到抽象类(因此构造函数 mapperConfiguration.CreateMap<bar, barContract>() 不正确),我想知道是否可以使用反射来查找所有“实现”条形类的类并“自动”映射它们

 var type = typeof(bar);
            var types = AppDomain.CurrentDomain.GetAssemblies()
                .SelectMany(s => s.GetTypes())
                .Where(p => type.IsAssignableFrom(p));

我有类型,我正在尝试调用 CreateMap。 由于类型现在是一个变量,我再次使用反射创建了一个泛型方法:

foreach (Type t in types)
{
mapperConfiguration.GetType().GetMethod("CreateMap")
              .MakeGenericMethod(t, typeof(barContract))
              .Invoke(mapperConfiguration, null);
}

问题是 CreateMap 不是从 mapperConfiguration 实例中提取的类型的成员 - 当我尝试按名称提取方法时,我得到空值。我看到它是在 IProfileExpression 中定义的,所以我试图从接口中提取方法: typeof(IProfileExpression).GetMethod("CreateMap") 并且我得到 System.Reflection.AmbiguousMatchException - 这还不错,但更具体地说,在 GetMethod 中使用 System.Reflection.BindingFlags 我又得到了空值。

我做错了什么,或者如何解决映射问题?

【问题讨论】:

    标签: c# reflection automapper


    【解决方案1】:

    您可以创建从一种类型到另一种类型的映射CreateMap(SouceType, DestinationType));

    public abstract class Bar
    {
        public string Field1 { get; set; }
    }
    
    public class Foo1bar : Bar
    {
        // members
    }
    
    public class Foo2bar : Bar
    {
        // members
    }
    
    public class BarContract
    {
        public string Field1 { get; set; }
    
        // this will use existing someClass.Description field
        public string Field2Description { get; set; }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            AutoMapperConfiguration.Init();
    
            var foo1 = new Foo1bar {Field1 = "One"};
            var barContract1=AutoMapperConfiguration.Mapper.Map<Foo1bar, BarContract>(foo1);
            Console.WriteLine("barContract1.Field1: " + barContract1.Field1);
    
            var foo2 = new Foo2bar {Field1 = "Two"};
            var barContract2=AutoMapperConfiguration.Mapper.Map<Foo2bar, BarContract>(foo2);
            Console.WriteLine("barContract2.Field1: " + barContract2.Field1);
    
            Console.ReadLine();
        }
    
        public static class AutoMapperConfiguration
        {
            public static void Init()
            {
                MapperConfiguration = new MapperConfiguration(cfg =>
                {
                    var types = Assembly.GetExecutingAssembly().GetTypes()
                        .Where(type => !string.IsNullOrEmpty(type.Namespace) &&
                                        type.BaseType != null &&
                                        type.BaseType == typeof(Bar));
                    foreach (Type type in types)
                    {
                        cfg.CreateMap(type, typeof(BarContract));
                    }
                });
    
                Mapper = MapperConfiguration.CreateMapper();
            }
    
            public static IMapper Mapper { get; private set; }
    
            public static MapperConfiguration MapperConfiguration { get; private set; }
        }
    }
    

    输出

    【讨论】:

      猜你喜欢
      • 2017-05-19
      • 2019-02-14
      • 2017-01-15
      • 1970-01-01
      • 2021-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-03
      相关资源
      最近更新 更多