在运行时操作Automapper的配置文件的映射表达式

Manipulate the mapping expression of the profile of Automapper at runtime

我有一些Automapper配置文件,我根据情况在运行时创建了两个不同的mapper实例。对于其中一个映射器实例,我需要在运行时忽略这些配置文件中映射的一些成员。考虑下面的示例,我该如何实现?

public class Foo
{
    public object SomeField { get; set; }
}

public class FooDto
{
    public object SomeField { get; set; }
}

public class FooProfile : Profile
{
    public FooProfile()
    {
        CreateMap<Foo, FooDto>();
    }
}

在运行时使用配置文件和不同的映射表达式创建多个映射器实例:

public class MapperFactory
{
    public IMapper Create(bool isSomeFieldIgnored)
    {
        MapperConfiguration configuration;
        if (isSomeFieldIgnored)
        {
            configuration = new MapperConfiguration(expression =>
            {
                expression.AddProfile<FooProfile>();
                // ignore the SomeField here!
            });
        }
        else
        {
            configuration = new MapperConfiguration(expression =>
            {
                expression.AddProfile<FooProfile>();
            });
        }

        return configuration.CreateMapper();
    }
}

也许您可以使用 opt.Condition() 而不是 opt.Ignore()?如果您可以让您的触发器基于静态条件忽略某个成员,那就是。

https://docs.automapper.org/en/stable/Conditional-mapping.html

“有条件地将此成员映射到源、目标、源和目标成员。”

我找不到在配置文件外更改映射表达式的方法,而且没有人回答。所以我不得不用另一种方式解决问题。下面的示例显示了使用配置文件构造函数中的参数将运行时条件应用于表达式的解决方案。

public class Foo
{
    public object SomeField { get; set; }
}

public class FooDto
{
    public object SomeField { get; set; }
}

public class FooProfile : Profile
{
    public FooProfile()
        : this(false)
    {
        // the profile must have a parameterless constructor.
    }

    public FooProfile(bool isSomeFieldIgnored)
    {
        var expression =
            CreateMap<Foo, FooDto>();

        // ignore the SomeField is necessary.
        if (isSomeFieldIgnored)
            expression.ForMember(fooDto => fooDto.SomeField,
                options => options.Ignore());
    }
}
    

配置文件在运行时被实例化,条件被传递给它的构造函数。因此,可以使用mapper factory来获取两个不同的mapper实例:

public class MapperFactory
{
    public IMapper Create(bool isSomeFieldIgnored)
    {
        var configuration = new MapperConfiguration(expression =>
        {
            // instantiate the profile at runtime and pass the isSomeFieldIgnore as 
            // its constructor argument.
            var fooProfile =
                (Profile)Activator.CreateInstance(typeof(FooProfile),
                    new object[] { isSomeFieldIgnored });

            expression.AddProfile(fooProfile);
        });

        return configuration.CreateMapper();
    }
}