从MapperConfiguration确定自定义ValueResolver

时间:2016-05-17 17:41:39

标签: c# reflection automapper

在应用程序启动时,我们创建一个新的MapperConfiguration并将其配置为使用我们的配置文件。在一些配置文件中,我们使用自定义ValueResolver进行数据转换。

配置完成后,我们可以执行类似这样的操作来检索所有映射的属性和类型。

var mapping = configuration.GetAllTypeMaps().FirstOrDefault();
if (!mapping.IsMapped())
    return;

var propertyInfo = mapping.SourceMember as PropertyInfo;
if (propertyInfo == null)
    return;

var sourceType = mapping.SourceType;
var destinationType = mapping.DestimationType;
var entry = new TranslationEntry(sourceType, destinationType);
entry.DestinationProperty = mapping.DestinationProperty.Name;
entry.DestinationPropertyType = mapping.DestinationPropertyType;
entry.SourceProperty = propertyInfo.Name;
entry.SourcePropertyType = propertyInfo.PropertyType;

在这个例子中,我只获得第一个映射,但这只是为了示例目的。我遇到的问题是确定在特定映射中使用的自定义解析器。

我发现任何带有自定义解析器的映射似乎都有一个DelegateBasedResolver<>

的值解析器
var resolver = (from a in mapping.GetSourceValueResolvers()
                let b = a.GetType()
                where b.IsGenericType 
                && b.GetGenericTypeDefinition() == typeof(DelegateBasedResolver<>)
                select a).FirstOrDefault();

这似乎有效,并且每当自定义解析器连接到映射解析器时都不为空。但就我而言,这已经到了。

我们说我有一个像这样的简单映射:

public class ExampleProfile : Profile
{
    protected override void Configure()
    {
        CreateMap<ExampleDto, ExampleSummary>()
            .ForMember(a => a.Id, a => a.MapFrom(b => b.ExampleId))
            .ForMember(a => a.IsEnabled, a => a.ResolveUsing<CustomStringToBooleanResolver>().FromMember(b => b.is_enabled));
    }
}

我试图从上面的映射中获得的是 CustomStringToBooleanResolver 类型或其实例。我想我知道如何执行解析器,但这不是我想要做的。有人有什么想法吗?

1 个答案:

答案 0 :(得分:0)

经过一些挖掘,我实际上通过从4.2.1升级到5.0的最新测试版找到了答案。

代码现在看起来像这样:

var entry = new TranslationEntry(sourceType, destinationType);
var propertyInfo = mapping.SourceMember as PropertyInfo;
if (propertyInfo == null && mapping.ValueResolverConfig != null)
{
    entry.Resolver = mapping.ValueResolverConfig.Type;
    var expression = mapping.ValueResolverConfig.SourceMember.Body as MemberExpression;

    if (expression != null)
        propertyInfo = expression.Member as PropertyInfo;
}

if (propertyInfo == null)
    return;

entry.DestinationProperty = mapping.DestinationProperty.Name;
entry.DestinationPropertyType = mapping.DestinationPropertyType;
entry.SourceProperty = propertyInfo.Name;
entry.SourcePropertyType = propertyInfo.PropertyType;