Я нашел эту документацию, которая пересылается на тесты github.
Проблема в том, что существуют только сопоставления открытого универсального типа с неуниверсальным типом с использованием IValueResolver или между открытым универсальным типом и открытый универсальный тип. Этот способ работает так, как ожидалось.
Что мне нужно сделать, так это сопоставить универсальный тип с неуниверсальным типом (это работает) и наоборот для десериализации.Мои типы:
Код: Выделить всё
public sealed class Foo
{
public T? Value { get; set; }
}
public sealed class SerializableFoo
{
public string? TypeAQN { get; set; }
public string? Data { get; set; }
}
Код: Выделить всё
// Working
this.CreateMap(typeof(Foo), typeof(SerializableFoo), MemberList.None)
.ForMember(nameof(SerializableFoo.TypeAQN), opt => opt.MapFrom(typeof(TypeAQNValueResolver)))
.ForMember(nameof(SerializableFoo.Data), opt => opt.MapFrom(typeof(DataValueResolver)));
// not working
this.CreateMap(typeof(SerializableFoo), typeof(Foo), MemberList.None)
.ForMember(nameof(Foo.Value), opt => opt.MapFrom(typeof(SerializableToFooValueResolver)));
private sealed class TypeAQNValueResolver : IValueResolver
{
public string? Resolve(Foo source, SerializableFoo destination, string? destMember, ResolutionContext context) =>
typeof(T).AssemblyQualifiedName;
}
private sealed class DataValueResolver : IValueResolver
{
///
public string? Resolve(Foo source, SerializableFoo destination, string? destMember, ResolutionContext context) =>
source.Value?.ToString() ?? "";
}

Код: Выделить всё
The number of generic arguments provided doesn't equal the arity of the generic type definition.
Parameter name: instantiation
Как происходит сопоставление неуниверсального типа с открытым универсальным типом с помощью IValueResolver работает?
ДЕМО dotnetfiddle
РЕДАКТИРОВАТЬ
Мне удалось поработайте над этой проблемой, представив интерфейс - но это кажется неправильным и работает только для очень конкретных известных обобщенных аргументов:
Код: Выделить всё
public interface IFoo
{
object? Value { get; set; }
}
public sealed class Foo : IFoo
{
public T? Value { get; set; }
object? IFoo.Value
{
get => this.Value;
set => this.Value = (T?)value;
}
}
Код: Выделить всё
this.CreateMap(typeof(SerializableFoo), typeof(IFoo), MemberList.None)
.IncludeAllDerived()
.ForMember(nameof(IFoo.Value), opt => opt.MapFrom(typeof(SerializableToFooValueResolver))); // Yes - generic CreateMap is now possible.
this.CreateMap(typeof(SerializableFoo), typeof(Foo), MemberList.None)
.IncludeBase(typeof(SerializableFoo), typeof(IFoo));
private sealed class SerializableToFooValueResolver : IValueResolver
{
///
public object? Resolve(SerializableFoo source, IFoo destination, object? destMember, ResolutionContext context)
{
var destinationType = destination.GetType();
if (destinationType.IsGenericType)
{
var genericArgType = destinationType.GetGenericArguments()[0];
if (genericArgType == typeof(double))
{
return double.Parse(source.Data ?? string.Empty);
}
}
return null;
}
}
Подробнее здесь: https://stackoverflow.com/questions/792 ... neric-type