如何使用泛型类型配置AutoMapper

Has*_*san 5 c# generics automapper

我试图在我的实体中实现属性版本跟踪.使用TrackedProperty我的可跟踪属性的模式;

public class PropertyVersion<TValue, TVersion>
{
    public TVersion Version { get; set; }
    public TValue Value { get; set; }
}


public class TrackedProperty<TValue, TVersion> : List<PropertyVersion<TValue, TVersion>>
{

}
Run Code Online (Sandbox Code Playgroud)

例如,在我的存储库中,我将保留TrackedFoo对象,并且我将能够在特定版本(在这种情况下,版本被描述为Time对象)中检索数据Foo.

public class TrackedFoo
{
    public string Id { get; set; }
    public TrackedProperty<string, DateTime> Name { get; set; }
}

public class Foo
{
    public string Id { get; set; }
    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我想尽可能保持通用.所以我尝试使用AutoMapper,但我无法以通用方式配置它,我不需要配置每个映射TrackedTypeXTypeX.

我需要在TrackedProperty中获取最后一个PropertyVersion项,并将其Value属性映射到TValue类型

能帮我找到解决这个问题的方法吗?

我可以减少变量类型的数量(就是你所谓的<>?之间的东西,无论如何)到单一使用

DateTrackedProperty<TValue> : TrackedProperty<TValue,DateTime>
IntegerTrackedProperty<TValue> : TrackedProperty<TValue, int>
StringTrackedProperty<TValue> : TrackedProperty<TValue, string>
Run Code Online (Sandbox Code Playgroud)

我很乐意为这三种类型编写AutoMapper配置.

Has*_*san 5

最后,我通过将以下内容放入我的 MappingProfile 中,设法创建了一个通用映射配置文件(只有一种方式)

CreateMap(typeof(PropertyVersion<,>), typeof(object)).ConvertUsing(typeof(PropertyVersionToValueConverter<,>));
CreateMap(typeof(TrackedProperty<,>), typeof(PropertyVersion<,>)).ConvertUsing(typeof(TrackedPropertyToPropertyVersionConverter<,>));
CreateMap(typeof(TrackedProperty<,>), typeof(object)).ConvertUsing(typeof(TrackedPropertyToValueConverter<,>));
Run Code Online (Sandbox Code Playgroud)

在哪里

public class PropertyVersionToValueConverter<TValue, TVersion> : ITypeConverter<PropertyVersion<TValue, TVersion>, TValue>
{
    public TValue Convert(PropertyVersion<TValue, TVersion> source, TValue destination, ResolutionContext context)
    {
        if (source != null)
            return source.Value;
        return default(TValue);
    }
}

public class TrackedPropertyToPropertyVersionConverter<TValue, TVersion> : ITypeConverter<TrackedProperty<TValue, TVersion>, PropertyVersion<TValue, TVersion>>
{
    public PropertyVersion<TValue, TVersion> Convert(TrackedProperty<TValue, TVersion> source, PropertyVersion<TValue, TVersion> destination, ResolutionContext context)
    {
        if (source != null && source.Count > 0)
            return source.Last();

        else return default(PropertyVersion<TValue, TVersion>);
    }
}

public class TrackedPropertyToValueConverter<TValue, TVersion> : ITypeConverter<TrackedProperty<TValue, TVersion>, TValue>
{
    public TValue Convert(TrackedProperty<TValue, TVersion> source, TValue destination, ResolutionContext context)
    {
        var vers = context.Mapper.Map(source, typeof(TrackedProperty<TValue, TVersion>), typeof(PropertyVersion<TValue,TVersion>));
        return (TValue)context.Mapper.Map(vers, typeof(PropertyVersion<TValue, TVersion>), typeof(TValue));
    }
}
Run Code Online (Sandbox Code Playgroud)

第一个映射行提取 PropertyVersion.Value。

第二个映射行假设我只需要 TrackedProperty 中的最后一个版本并提取该版本。

第三行将所有内容结合在一起。

我可能可以将所有内容合二为一,并拥有一条 CreateMap 行和一个 Converter,但这很简单。