将封装的属性映射到 IEnumerable

本文关键字:IEnumerable 映射 属性 封装 | 更新日期: 2023-09-27 18:35:27

给定以下类

public class Foo {
    public string Name { get; set; }
}
public class Bar {
    public string Name { get; set; }
}
public class Foos : IEnumerable<Foo> {
    private IList<Foo> _foos;
    public Foos(int max = 10)
    {
        _foos = Enumerable.Range(0, max)
            .Select(i => new Foo() { Name = "Foo" + i})
            .ToList();
    }
    public IEnumerator<Foo> GetEnumerator()
    {
        return _foos.GetEnumerator();
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

和以下映射:

Mapper.CreateMap<Foo, Bar>();

我可以通过以下方式将Foos映射到IEnumerable<Bar>

Mapper.Map<IEnumerable<Bar>>(new Foos(5));

但是,如果我有一个额外的类,如下所示:

public class FooContainer {
    private Foos _foos;
    public FooContainer()
    {
        _foos = new Foos(5);
    }
    public Foos Foos { get { return _foos; } }
}

我将如何设置映射以便FooContainer映射到IEnumerable<Bar>

编辑

好的,只是为了澄清这个问题 - 如果我有以下三个类:

public class Foo {
    public string Name { get; set; }
}
public class Bar {
    public Guid SourceId { get; set; }
    public string Name { get; set; }
}
public class FooContainer {
    public Guid Id { get; set; }
    public List<Foo> Foos { get; set; }
}

如何设置FooContainerIEnumerable<Bar>的映射,以便FooContainer.Id映射到每个Bar.SourceIdFoo.Name映射到Bar.Name

将封装的属性映射到 IEnumerable

对于复杂的逻辑,您可以实现一个ITypeConverter

public class FooContainerTypeConverter
    : ITypeConverter<FooContainer, IEnumerable<Bar>>
{
    public IEnumerable<Bar> Convert(ResolutionContext context)
    {
        var source = context.SourceValue as FooContainer;
        if(source == null)
        {
            return Enumerable.Empty<Bar>();
        }
        var result = source.Foos.Select(foo => MapBar(foo, source.Id));
        return result;
    }
    private static Bar MapBar(Foo item, Guid id)
    {
        // Use the existing Foo => Bar mapping
        var bar = Mapper.Map<Foo,Bar>(item);
        bar.Id = id;
        return bar;
    }
}

用法:

Mapper.CreateMap<FooContainer, IEnumerable<Bar>>()
      .ConvertUsing<FooContainerTypeConverter>();