Я пытаюсь построить иерархию профилей сопоставления, чтобы упростить создание сопоставлений для новых объектов, которые вписываются в эту иерархию.Но у меня проблемы с получением некоторых сопоставлений для работы.Отображение, которое я добавил с использованием параметра универсального типа, похоже, не работает, когда это тип назначения, однако оно работает, когда это тип источника.
Рассмотрим следующие типы:
public interface IRequest
{
string Input { get; }
}
public interface IResponse
{
string Output { get; }
}
public class SomeObject
{
public string Value { get; set; }
}
abstract class BaseProfile<TSource, TDestination> : Profile
where TSource : IRequest
where TDestination : IResponse
{
protected BaseProfile()
{
CreateMap<TSource, SomeObject>()
.ForMember(src => src.Value, opt => opt.MapFrom(dest => dest.Input));
CreateMap<SomeObject, TDestination>()
.ForMember(src => src.Output, opt => opt.MapFrom(dest => dest.Value));
}
}
Я хочу иметь возможность сделать так, чтобы профиль для конкретных типов мог использовать сопоставления в этом родительском профиле, чтобы я мог определить это:
class FooRequest : IRequest
{
public string Input { get; set; }
}
class FooResponse : IResponse
{
public string Output { get; set; }
}
class FooProfile : BaseProfile<FooRequest, FooResponse>
{
public FooProfile()
{
}
}
Однако сопоставление с объектом ответа нене отображается вообще.
Mapper.Initialize(c => c.AddProfiles(typeof(FooProfile).Assembly));
var request = new FooRequest { Input = "FOO" };
var obj = Mapper.Map<SomeObject>(request); // this works
// obj.Value = "FOO"
var response = Mapper.Map<FooResponse>(obj); // this doesn't
// response.Output = null
Кажется, это можно исправить, мне нужно продублировать отображение, которое, как я думал, я уже создал, но используя конкретный тип.
public FooProfile()
{
// Adding this works
CreateMap<SomeObject, FooResponse>()
.ForMember(src => src.Output, opt => opt.MapFrom(dest => dest.Value));
}
Естьчто-то мне не хватает, чтобы сделать эту работу?Или мне придется каждый раз создавать эти явные отображения?
Как указывалось в ответе Скотта, проблема в конечном счете заключается в том, что интерфейс, которым ограничен универсальный параметр, не имеет настраиваемых свойств.Но Надер также обнаружил, что использование определенной перегрузки метода ForMember()
работает.Таким образом, вместо привязки к члену напрямую, мы связываемся с именем участника.Это прекрасно работает для моих нужд.
protected BaseProfile()
{
CreateMap<TSource, SomeObject>()
.ForMember(src => src.Value, opt => opt.MapFrom(dest => dest.Input));
CreateMap<SomeObject, TDestination>()
.ForMember(nameof(IResponse.Output), opt => opt.MapFrom(dest => dest.Value));
}