Automapper - 可插入映射
Automapper - Pluggable mapping
我需要实现一个可插入系统,其中 Automapper 配置文件可以由许多 DLL 提供。
要映射的对象有人物列表:
public class CompanySrc
{
public List<PersonSrc> Persons {get;set;}
}
public class CompanyDest
{
public List<PersonDest> Persons {get;set;}
}
PersonSrc 和 PersonDest 是抽象的类,可以在每个 DLL 中扩展:
DLL1:
public class EmployeeSrc : PersonSrc
{
...
}
public class EmployeeDest : PersonDest
{
...
}
DLL2:
public class ManagerSrc : PersonSrc
{
...
}
public class ManagerDest : PersonDest
{
...
}
我的想法是实现类似这样的东西:
public class DLL1Profile : Profile
{
public DLL1Profile()
{
CreateMap<PersonSrc, PersonDest>()
.Include<EmployeeSrc, EmployeeDest>();
CreateMap<EmployeeSrc, EmployeeDest>();
}
}
public class DLL2Profile : Profile
{
public DLL2Profile()
{
CreateMap<PersonSrc, PersonDest>()
.Include<ManagerSrc, ManagerDest>();
CreateMap<ManagerSrc, ManagerDest>();
}
}
映射是通过以下方式完成的
var mc = new MapperConfiguration(cfg =>
{
cfg.CreateMap<CompanySrc, CompanyDest>()
cfg.AddProfile(new DLL1Profile());
cfg.AddProfile(new DLL2Profile ());
});
IMapper sut = mc.CreateMapper();
var result = sut.Map<CompanyDest>(companySrc);
但这种方法不起作用。当 "People" 列表包含一名员工和一名经理时,我尝试映射整个列表时出现异常。
有什么建议吗?
您遇到此问题是因为您多次调用 CreateMap<PersonSrc, PersonDest>()
- 只能存在一个映射。
当您在不同的 DLL 中扩展基础 class 时,请勿使用 .Include
,而应使用 .IncludeBase
。包含要求包含您的基础 class 的配置文件能够引用派生的 class,这很可能不是您想要的。
您应该在常见的地方定义基本映射,大概是在定义 Person 的地方:
CreateMap<PersonSrc, PersonDest>();
在您的 DLL1 配置文件等中,改用 IncludeBase
:
CreateMap<ManagerSrc, ManagerDest>()
.IncludeBase<PersonSrc, PersonDest>();
我需要实现一个可插入系统,其中 Automapper 配置文件可以由许多 DLL 提供。
要映射的对象有人物列表:
public class CompanySrc
{
public List<PersonSrc> Persons {get;set;}
}
public class CompanyDest
{
public List<PersonDest> Persons {get;set;}
}
PersonSrc 和 PersonDest 是抽象的类,可以在每个 DLL 中扩展:
DLL1:
public class EmployeeSrc : PersonSrc
{
...
}
public class EmployeeDest : PersonDest
{
...
}
DLL2:
public class ManagerSrc : PersonSrc
{
...
}
public class ManagerDest : PersonDest
{
...
}
我的想法是实现类似这样的东西:
public class DLL1Profile : Profile
{
public DLL1Profile()
{
CreateMap<PersonSrc, PersonDest>()
.Include<EmployeeSrc, EmployeeDest>();
CreateMap<EmployeeSrc, EmployeeDest>();
}
}
public class DLL2Profile : Profile
{
public DLL2Profile()
{
CreateMap<PersonSrc, PersonDest>()
.Include<ManagerSrc, ManagerDest>();
CreateMap<ManagerSrc, ManagerDest>();
}
}
映射是通过以下方式完成的
var mc = new MapperConfiguration(cfg =>
{
cfg.CreateMap<CompanySrc, CompanyDest>()
cfg.AddProfile(new DLL1Profile());
cfg.AddProfile(new DLL2Profile ());
});
IMapper sut = mc.CreateMapper();
var result = sut.Map<CompanyDest>(companySrc);
但这种方法不起作用。当 "People" 列表包含一名员工和一名经理时,我尝试映射整个列表时出现异常。 有什么建议吗?
您遇到此问题是因为您多次调用 CreateMap<PersonSrc, PersonDest>()
- 只能存在一个映射。
当您在不同的 DLL 中扩展基础 class 时,请勿使用 .Include
,而应使用 .IncludeBase
。包含要求包含您的基础 class 的配置文件能够引用派生的 class,这很可能不是您想要的。
您应该在常见的地方定义基本映射,大概是在定义 Person 的地方:
CreateMap<PersonSrc, PersonDest>();
在您的 DLL1 配置文件等中,改用 IncludeBase
:
CreateMap<ManagerSrc, ManagerDest>()
.IncludeBase<PersonSrc, PersonDest>();