AutoMapper - 在没有 `set;` 实现的情况下映射 属性

AutoMapper - map a property without a `set;` implementation

有什么方法可以映射没有 set; 方法的 IList<> 属性 吗?

来源Class:

public class SourceClass
{
    private IList<string> strings;

    public IList<string> Strings { get { return this.strings; } }

    public SourceClass() { this.strings = new List<string>() { "s1", "s2", "s3" };
    //...
}

目的地Class:

public class DestinationClass
{
    private IList<string> strings;

    public IList<string> Strings { get { return this.strings; } }

    public DestinationClass() { this.strings = new List<string>();
    //...
}

如您所见,class 都没有实现 set;。结果是当我执行AutoMapper.Mapper.Map<SourceClass, DestinationClass>(source, destination)时,Strings属性是空的

显而易见的解决方案是提供一个 set; 实现 DestinationClass,但是,我想知道如何提供自定义配置以处理这些麻烦。

目前我的配置是:

public class XProfile : AutoMapper.Profile
{
    protected override void Configure()
    {
        AutoMapper.Mapper.CreateMap<SourceClass, DestinationClass>();
    }
}

如果您使用的是不可变对象,我建议您将其作为参数传递给目标 class,它会像这样:

AutoMapper.Mapper.CreateMap<SourceClass, DestinationClass>()
  .ConstructUsing(s => new DestinationClass(s.Strings))

DestinationClass:

public class DestinationClass
{
    private IList<string> strings;

    public IList<string> Strings { get { return this.strings; } }

    public DestinationClass(List<string> strings = null)
    { 
        this.strings = strings ?? new List<string>();
    }
   //...
}

您可以配置 AutoMapper 以识别 non-public 成员。 查看 documentation

您可以像这样创建构造函数。

public class DestinationClass
{
    private IList<string> strings;

    public IList<string> Strings { get { return this.strings; } }

    public DestinationClass() : this(new List<string>()) { }

    public DestinationClass(IList<string> strs) {
        strings = strs.ToList(); // clone it
    }
    //...
}

然后你可以用ConstructUsing方法进行映射,告诉AutoMapper调用你创建的构造函数。

public class XProfile : AutoMapper.Profile
{
    protected override void Configure()
    {
        AutoMapper.Mapper.CreateMap<SourceClass, DestinationClass>()
            .ConstructUsing(x => new DestinationClass(x.Strings));
    }
}