使用AutoMapper自定义映射 [英] Custom Mapping with AutoMapper

查看:470
本文介绍了使用AutoMapper自定义映射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个非常简单的对象:

I have two very simple objects:

public class CategoryDto
{
    public string Id { get; set; }

    public string MyValueProperty { get; set; }
}

public class Category
{
    public string Id { get; set; }

    [MapTo("MyValueProperty")]
    public string Key { get; set; }
}

当使用AutoMapper将Category映射到CategoryDto时,我想要以下行为:

When mapping a Category to a CategoryDto with AutoMapper, I would like the following behavior:

除了具有MapTo属性的属性外,应按常规映射属性.在这种情况下,我必须读取Attribute的值以找到目标属性. source属性的值用于查找要注入目标属性的值(借助字典).一个例子总是最好是1000个单词...

The properties should be mapped as usual, except for those that have the MapTo attribute. In this case, I have to read the value of the Attribute to find the target property. The value of the source property is used to find the value to inject in the destination property (with the help of a dictionary). An example is always better that 1000 words...

示例:

Dictionary<string, string> keys = 
    new Dictionary<string, string> { { "MyKey", "MyValue" } };

Category category = new Category();
category.Id = "3";
category.Key = "MyKey";

CategoryDto result = Map<Category, CategoryDto>(category);
result.Id               // Expected : "3"
result.MyValueProperty  // Expected : "MyValue"

Key属性被映射到MyValueProperty(通过MapTo属性),并且分配的值是"MyValue",因为源属性值是"MyKey",其被(通过字典)映射到"MyValue".

The Key property is mapped to the MyValueProperty (via the MapTo Attribute), and the assigned value is "MyValue", because the source property value is "MyKey" which is mapped (via dictionary) to "MyValue".

使用AutoMapper可以吗?当然,我需要一个适用于每个对象的解决方案,而不仅适用于Category/CategoryDto.

Is this possible using AutoMapper ? I need of course a solution that works on every object, not just on Category/CategoryDto.

推荐答案

我终于(经过这么长时间!!!!)找到了解决方案. 我与社区分享;希望它将对其他人有帮助...

I finally (after so many hours !!!!) found a solution. I share this with the community; hopefully it will help someone else...

请注意,它现在更加简单(AutoMapper 5.0+),您可以像我在这篇文章中回答的那样进行操作:

Note that it's now much simpler (AutoMapper 5.0+), you can do like I answered in this post: How to make AutoMapper truncate strings according to MaxLength attribute?

public static class Extensions
{
    public static IMappingExpression<TSource, TDestination> MapTo<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
    {
        Type sourceType = typeof(TSource);
        Type destinationType = typeof(TDestination);

        TypeMap existingMaps = Mapper.GetAllTypeMaps().First(b => b.SourceType == sourceType && b.DestinationType == destinationType);
        string[] missingMappings = existingMaps.GetUnmappedPropertyNames();

        if (missingMappings.Any())
        {
            PropertyInfo[] sourceProperties = sourceType.GetProperties();
            foreach (string property in missingMappings)
            {
                foreach (PropertyInfo propertyInfo in sourceProperties)
                {
                    MapToAttribute attr = propertyInfo.GetCustomAttribute<MapToAttribute>();
                    if (attr != null && attr.Name == property)
                    {
                        expression.ForMember(property, opt => opt.ResolveUsing(new MyValueResolve(propertyInfo)));
                    }
                }
            }
        }

        return expression;
    }
}

public class MyValueResolve : IValueResolver
{
    private readonly PropertyInfo pInfo = null;

    public MyValueResolve(PropertyInfo pInfo)
    {
        this.pInfo = pInfo;
    }

    public ResolutionResult Resolve(ResolutionResult source)
    {
        string key = pInfo.GetValue(source.Value) as string;
        string value = dictonary[key];
        return source.New(value);
    }
}

这篇关于使用AutoMapper自定义映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆