我需要从n个类创建一个映射(使用AutoMapper),所有类都从一个抽象类派生到一个契约类
例如:
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>()
不正确),我想知道是否可以使用反射来查找所有类'实现'bar类并自动'映射'
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实例中提取的类型的成员 - 当我尝试按名称提取方法时,我得到null。我看到它在IProfileExpression中定义,所以我试图从界面中提取方法:
typeof(IProfileExpression).GetMethod("CreateMap")
我得到System.Reflection.AmbiguousMatchException - 什么是好的,但是在GetMethod中使用System.Reflection.BindingFlags更具体我再次得到空值。
我做错了什么,或者如何解决这个映射问题?
答案 0 :(得分:2)
您可以创建从一种类型到另一种类型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; }
}
}