0

在以前版本的 AutoMapper 中,我创建了一个通用 PreCondition 来有条件地映射/不映射某些成员。我通过将成员名称数组添加到 Map 选项并根据当前正在映射的成员检查此列表来实现这一点,如下面的代码所示。

不幸的是,MemberName 不再在 ResolutionContext 中公开,所以我不知道当前正在映射哪个成员。我在新精简的 ResolutionContext 中找不到任何可以引导我获取此信息的内容。

我知道我可以编写很多特定的前提条件案例,但我将其用于数以万计的类型。有谁知道获取当前 MemberName 的其他方法?

using System;
using System.Collections.Generic;
using System.Linq;
using AutoMapper;

public class AutoMapperTest
{
    public class SomeSourceType
    {
        public string String1;
        public string String2;
        public string String3;
    }

    public class SomeDestinationType
    {
        public string String1;
        public string String2;
        public string String3;
    }

    public void Test()
    {
        Mapper.Initialize(cfg =>
        {
            cfg.CreateMap<SomeSourceType, SomeDestinationType>();

            cfg.ForAllMaps((Action<TypeMap, IMappingExpression>)((typeMap, map) =>
            {
                map.ForAllMembers(opt =>
                {
                    opt.PreCondition(context =>
                    {
                        var optionsItems = context.Options.Items;
                        var propertiesToMap = (IEnumerable<string>)(optionsItems.Keys.Contains("PropertiesToMap") ? optionsItems["PropertiesToMap"] : null);

                        // The following line no longer works because MemberName is no longer exposed!
                        return (propertiesToMap == null) || propertiesToMap.Contains(context.MemberName);
                    });
                });
            }));
        });

        var source = new SomeSourceType() { String1 = "Hello", String2 = "World" };

        // This will map ALL properties.
        var dest = Mapper.Map<SomeSourceType, SomeDestinationType>(source);

        // This will only map String1 and String3.
        dest = Mapper.Map<SomeSourceType, SomeDestinationType>(source, opts => opts.Items.Add("PropertiesToMap", new string[] { "String1", "String3" }));
    }
}
4

1 回答 1

1

你快到了。“opt”参数是 type IMemberConfigurationExpression,它包含目标成员作为属性。这是您更新的示例:

using System;
using System.Collections.Generic;
using System.Linq;
using AutoMapper;

public class AutoMapperTest
{
    public class SomeSourceType
    {
        public string String1;
        public string String2;
        public string String3;
    }

    public class SomeDestinationType
    {
        public string String1;
        public string String2;
        public string String3;
    }

    public void Test()
    {
        Mapper.Initialize(cfg =>
        {
            cfg.CreateMap<SomeSourceType, SomeDestinationType>();

            cfg.ForAllMaps((Action<TypeMap, IMappingExpression>)((typeMap, map) =>
            {
                map.ForAllMembers(opt =>
                {
                    opt.PreCondition(context =>
                    {
                        var optionsItems = context.Options.Items;
                        var propertiesToMap = (IEnumerable<string>)(optionsItems.Keys.Contains("PropertiesToMap") ? optionsItems["PropertiesToMap"] : null);

                        return (propertiesToMap == null) || propertiesToMap.Contains(opt.DestinationMember.Name);
                    });
                });
            }));
        });

        var source = new SomeSourceType() { String1 = "Hello", String2 = "World" };

        var dest = Mapper.Map<SomeSourceType, SomeDestinationType>(source);

        dest = Mapper.Map<SomeSourceType, SomeDestinationType>(source, opts => opts.Items.Add("PropertiesToMap", new string[] { "String1", "String3" }));
    }
}
于 2016-11-21T15:15:43.197 回答