简述:我在使用多态映射时遇到了问题。我创建了一个GitHub存储库,其中包含一个测试套件,以说明我的问题。请在此处查找链接: LINK TO REPO
我正在实施保存/加载功能。为了实现这一点,我需要确保我正在序列化的领域模型以一种序列化友好的方式呈现。为此,我创建了一组DTOs,其中包含执行有意义的保存或加载所需的最少信息。
如下是领域模型的示例:
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,从而得到一个包含IDto适当实现的DtoCollection实例,这些实现与域映射相对应。反之亦然。
这里有一个小技巧,不同的具体域类型来自不同的插件程序集,因此我需要找到一种优雅的方式让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被映射到Domain(考虑Load)时,AutoMapper会创建IDomainType的代理,而不是将其解析为域。
我怀疑问题出在我的映射配置文件中,但我已经无法解决了。感谢您提前的帮助。
这里是另一个GitHub存储库的链接:Here's another link to the github repo