AutoMapper如何将接口映射到接口或对象

3
最初的回答: 如何将继承自一个接口的对象映射到继承自另一个接口的对象。
我有这样的代码结构:
public interface IDataTranslatable
{
    List<DataTranslation> SpanishDataTranslations {get;set;}
}

public interface IDataTranslatableDto
{
    List<DataTranslationDto> DataTranslations { get; set; }
}

对象 DataTranslationDataTranslationDto 拥有相同的属性。 我有许多从接口 IDataTranslatableIDataTranslatableDto 继承而来的对象。例如:


public class Category : IDataTranslatable
{
    public string Name { get; set; }
    public ICollection<DataTranslation> SpanishDataTranslations { get; set; } = new List<DataTranslation>();
}

public class CategoryDto : IDataTranslatableDto
{
    public string Name { get; set; }
    public List<DataTranslationDto> DataTranslations { get; set; } = new List<DataTranslationDto>();
}

最好的实现方式对我来说应该是这样的:
config.CreateMap<IDataTranslatable, IDataTranslatableDto>()
.ForMember(dest => dest.DataTranslations, opts => opts.MapFrom(src => src.SpanishDataTranslations));

我的意思是任何继承自IDataTranslatable的对象都必须映射到继承自IDataTranslatableDto的对象来对应字段。

但这样做不起作用,所以我尝试像这样进行映射

注:Original Answer翻译成"最初的回答"

config.CreateMap<IDataTranslatable, CategoryDto>()
.ForMember(dest => dest.DataTranslations, opts => opts.MapFrom(src => src.SpanishDataTranslations));

最初的回答

当前使用

public class AutoMapperConfiguration : IAutoMapperConfiguration
{
    public void Configure(IMapperConfigurationExpression config)
    {
        IDataTranslatableMappings(config);
    }

    private void IDataTranslatableMappings(IMapperConfigurationExpression config)
    {
        var mapCategory = config.CreateMap<Category, CategoryDto>().ForMember(dest => dest.DataTranslations, opts => opts.MapFrom(src => src.SpanishDataTranslations));
    }
}

这个变体效果不太好。我尝试解释我的想法,怎样做会更好?最初的回答。

请问您能展示一下mapper的使用方法吗?(您是将其映射到接口还是具体的类?) - Dominik
@Dominik 如果无法通过接口进行映射,我会直接进行映射。感谢您的帮助! - ovasylenko
1个回答

6
您可以按照以下方式进行配置:
Mapper.Initialize(config =>
{
    config.CreateMap<IDataTranslatable, IDataTranslatableDto>()
                .ForMember(x => x.DataTranslations, y => y.MapFrom(src => src.SpanishDataTranslations));
                
    config.CreateMap<Category, CategoryDto>()
                .IncludeBase<IDataTranslatable, IDataTranslatableDto>();                    

    config.CreateMap<DataTranslation, DataTranslationDto>();
});

而它的使用:

var translation = new DataTranslation()
{
    Test = "Foo"
};

IDataTranslatable category = new Category()
{
     SpanishDataTranslations = new List<DataTranslation> { translation }
};

var result = Mapper.Map<IDataTranslatableDto>(category);

您将被强制添加每个 IDataTranslatableIDataTranslatableDto 的实现到映射配置中。


更新

从8.0版本开始,您可以在基础类型上使用IncludeDerived,因此不再需要显式声明接口的所有实现。


IncludeDerived不适用于此,还是我理解有误? - sommmen
1
@sommen 是的,它只包含在8.0及以上版本中。我相信大多数人仍在使用<8.0。 - Dominik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接