TL;DR:我在多态映射方面遇到了麻烦。我已经制作了一个 github 存储库,其中包含一个测试套件来说明我的问题。请在这里找到它:回购链接 https://github.com/780Farva/AutoMapperInquiry
我正在努力实现保存/加载功能。为了实现这一点,我需要确保我正在序列化的域模型以序列化友好的方式表示。为了实现这一目标,我创建了一组 DTO,其中包含进行有意义的保存或加载所需的最低限度的信息集。
对于域来说是这样的:
public interface IDomainType
{
int Prop0 { get; set; }
}
public class DomainType1 : IDomainType
{
public int Prop1 { get; set; }
public int Prop0 { get; set; }
}
public class DomainType2 : IDomainType
{
public int Prop2 { get; set; }
public int Prop0 { get; set; }
}
public class DomainCollection
{
public IEnumerable<IDomainType> Entries { get; set; }
}
...对于 DTO
public interface IDto
{
int P0 { get; set; }
}
public class Dto1 : IDto
{
public int P1 { get; set; }
public int P0 { get; set; }
}
public class Dto2 : IDto
{
public int P2 { get; set; }
public int P0 { get; set; }
}
public class DtoCollection
{
private readonly IList<IDto> entries = new List<IDto>();
public IEnumerable<IDto> Entries => this.entries;
public void Add(IDto entry) { this.entries.Add(entry); }
}
这个想法是 DomainCollection 代表应用程序的当前状态。目标是将 DomainCollection 映射到 DtoCollection 会生成一个 DtoCollection 实例,该实例在映射到域时包含 IDto 的适当实现。反之亦然。
这里的一个额外技巧是,不同的具体域类型来自不同的插件程序集,因此我需要找到一种优雅的方法来让 AutoMapper(或类似的,如果您知道更好的映射框架)为我完成繁重的工作。
使用 Structuremap,我已经能够从插件中找到并加载所有配置文件,并使用它们配置应用程序 IMapper。
我尝试过创建这样的配置文件......
public class CollectionMappingProfile : Profile
{
public CollectionMappingProfile()
{
this.CreateMap<IDomainType, IDto>().ForMember(m => m.P0, a => a.MapFrom(x => x.Prop0)).ReverseMap();
this.CreateMap<DtoCollection, DomainCollection>().
ForMember(fc => fc.Entries, opt => opt.Ignore()).
AfterMap((tc, fc, ctx) => fc.Entries = tc.Entries.Select(e => ctx.Mapper.Map<IDomainType>(e)).ToArray());
this.CreateMap<DomainCollection, DtoCollection>().
AfterMap((fc, tc, ctx) =>
{
foreach (var t in fc.Entries.Select(e => ctx.Mapper.Map<IDto>(e))) tc.Add(t);
});
}
public class DomainProfile1 : Profile
{
public DomainProfile1()
{
this.CreateMap<DomainType1, Dto1>().ForMember(m => m.P1, a => a.MapFrom(x => x.Prop1))
.IncludeBase<IDomainType, IDto>().ReverseMap();
}
}
public class DomainProfile2 : Profile
{
public DomainProfile2()
{
this.CreateMap<DomainType2, IDto>().ConstructUsing(f => new Dto2()).As<Dto2>();
this.CreateMap<DomainType2, Dto2>().ForMember(m => m.P2, a => a.MapFrom(x => x.Prop2))
.IncludeBase<IDomainType, IDto>().ReverseMap();
}
}
然后,我编写了一个测试套件,以确保在将此功能与应用程序集成时映射将按预期运行。我发现每当 DTO 映射到域(例如 Load)时,AutoMapper 都会创建 IDomainType 的代理,而不是将它们解析到域。
我怀疑问题出在我的地图配置文件上,但我已经没有人才了。预先感谢您的意见。
这是 github 存储库的另一个链接 https://github.com/780Farva/AutoMapperInquiry