'automapper map interface to interface or object
How to map objects inherited from one interface to objects inherited from another interface.
I have such code structure
public interface IDataTranslatable
{
List<DataTranslation> SpanishDataTranslations {get;set;}
}
public interface IDataTranslatableDto
{
List<DataTranslationDto> DataTranslations { get; set; }
}
objects DataTranslation
and DataTranslationDto
have the same properties.
I have many objects inherited from IDataTranslatable
and IDataTranslatableDto
interfaces. For example
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>();
}
The best implementation for me would be something like that
config.CreateMap<IDataTranslatable, IDataTranslatableDto>()
.ForMember(dest => dest.DataTranslations, opts => opts.MapFrom(src => src.SpanishDataTranslations));
By this I mean that any object inherited from IDataTranslatable
has to be mapped to object inherited IDataTranslatableDto
to corresponding fields.
But this won't work, So I've tried to map like that
config.CreateMap<IDataTranslatable, CategoryDto>()
.ForMember(dest => dest.DataTranslations, opts => opts.MapFrom(src => src.SpanishDataTranslations));
Current using
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));
}
}
This variant doesn't work as well. I've tried to explain my idea, how would be better to do it?
Solution 1:[1]
You can configure it the following way:
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>();
});
And the usage of it:
var translation = new DataTranslation()
{
Test = "Foo"
};
IDataTranslatable category = new Category()
{
SpanishDataTranslations = new List<DataTranslation> { translation }
};
var result = Mapper.Map<IDataTranslatableDto>(category);
You will be forced to add every implementation of IDataTranslatable
and IDataTranslatableDto
to the mapping configuration.
Update
From version 8.0 and above, you can use IncludeDerived
on your base type and therefore no longer need to explicitly declare all implementations of your interface.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |