自动映射器将接口映射到接口或对象

ova*_*nko 3 .net c# asp.net automapper asp.net-core

如何将从一个接口继承的对象映射到从另一接口继承的对象。

我有这样的代码结构

public interface IDataTranslatable
{
    List<DataTranslation> SpanishDataTranslations {get;set;}
}

public interface IDataTranslatableDto
{
    List<DataTranslationDto> DataTranslations { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

对象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>();
}
Run Code Online (Sandbox Code Playgroud)

对我来说最好的实现是这样的

config.CreateMap<IDataTranslatable, IDataTranslatableDto>()
.ForMember(dest => dest.DataTranslations, opts => opts.MapFrom(src => src.SpanishDataTranslations));
Run Code Online (Sandbox Code Playgroud)

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

但这是行不通的,所以我尝试这样映射

config.CreateMap<IDataTranslatable, CategoryDto>()
.ForMember(dest => dest.DataTranslations, opts => opts.MapFrom(src => src.SpanishDataTranslations));
Run Code Online (Sandbox Code Playgroud)

目前使用

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));
    }
}
Run Code Online (Sandbox Code Playgroud)

这个变体也不起作用。我试图解释我的想法,怎样做会更好?

Dom*_*nik 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>();
});
Run Code Online (Sandbox Code Playgroud)

以及它的用法:

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

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

var result = Mapper.Map<IDataTranslatableDto>(category);
Run Code Online (Sandbox Code Playgroud)

您将被迫将IDataTranslatable和的每个实现添加IDataTranslatableDto到映射配置中。


更新

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