Automapper Интерфейс имеет конфликтующий идентификатор свойства Имя параметра: interfaceType
Это моя модель Heirarchy:
public interface INodeModel<T> : INodeModel
where T : struct
{
new T? ID { get; set; }
}
public interface INodeModel
{
object ID { get; set; }
string Name { get; set; }
}
public class NodeModel<T> : INodeModel<T>
where T : struct
{
public T? ID { get; set; }
public string Name { get; set; }
object INodeModel.ID
{
get
{
return ID;
}
set
{
ID = value as T?;
}
}
}
public class NodeDto<T> where T : struct
{
public T? ID { get; set; }
public string Name { get; set; }
}
и это мои отображения и тест:
class Program
{
private static MapperConfiguration _mapperConfiguration;
static void Main(string[] args)
{
_mapperConfiguration = new MapperConfiguration(cfg =>
{
cfg.CreateMap(typeof(NodeDto<>), typeof(NodeModel<>));
cfg.CreateMap(typeof(NodeDto<>), typeof(INodeModel<>));
cfg.CreateMap(typeof(INodeModel<>), typeof(NodeModel<>));
});
var dto = new NodeDto<int> { ID = 1, Name = "Hi" };
var obj = _mapperConfiguration.CreateMapper().Map<INodeModel<int>>(dto);
Console.Write(obj.ID);
Console.ReadLine();
}
}
и вот исключение:
AutoMapper.AutoMapperMappingException:
Типы картографирования:
NodeDto 1 -> INodeModel
1 NodeDto`1 [[System.Int32] ->
INodeModel`1 [[System.Int32]
Сообщение:
Интерфейс имеет конфликтующий идентификатор свойства Имя параметра: interfaceType
стек:
в AutoMapper.Internal.ProxyGenerator. CreateProxyType (Тип interfaceType)
в AutoMapper.Internal.ProxyGenerator. GetProxyType (Тип interfaceType)
в AutoMapper.MappingEngine. CreateObject (ResolutionContext context)
1 ответ
AutoMapper смущен при создании прокси-реализации, когда в ваших интерфейсах есть два члена с одинаковыми именами. Вы используете затенение, которое еще сложнее. Вместо того, чтобы предполагать, что AutoMapper может в этом разобраться, что, к счастью, объясняю новому члену команды, я бы вместо этого сделал реализацию класса интерфейса явной:
cfg.CreateMap(typeof(NodeDto<>), typeof(NodeModel<>));
cfg.CreateMap(typeof(NodeDto<>), typeof(INodeModel<>))
.ConvertUsing(typeof(NodeModelConverter<>));
cfg.CreateMap(typeof(INodeModel<>), typeof(NodeModel<>));
public class NodeModelConverter<T> :
ITypeConverter<NodeModel<T>, INodeModel<T>> where T : struct
{
public INodeModel<T> Convert(NodeModel<T> source, ResolutionContext context)
=> new NodeModelImpl {ID = source.ID, Name = source.Name};
private class NodeModelImpl : INodeModel<T>
{
public T? ID { get; set; }
public string Name { get; set; }
object INodeModel.ID
{
get { return ID; }
set { ID = (T?) value; }
}
}
}
Никакой магии, и совершенно явно и очевидно!