0

我在两个不同的命名空间下有以下这些类,例如SourceTarget.

映射类:

public class Instance
{
    public Type Type { get; set; }
    public object Definition { get; set; }
}

public sealed class Class : Instance
{
    private IList<Property> m_Properties;
    public IList<Property> Properties
    {
        get { return m_Properties ?? (m_Properties = new List<Property>()); }
    }
}

public abstract class Member : Instance
{
    public string Name { get; set; }
}

public sealed class Parameter : Member
{
}

public sealed class Property : Member
{
}

请注意,Instance该类具有Definitionobject 类型的属性,该属性将保存Class引用,因此嵌套层次结构将从这里开始直到 N 级。我转换得很好,但内部的定义属性Class及其嵌套层次结构对象仍然持有源引用而不是目标。在添加ForMember(t => t.Definition, opt => opt.MapFrom(s => Mapper.Map<Source.Class, Target.Class>((Source.Class)s.Definition)))以某种方式使这种转换工作之后,它已经开始给出异常。

用法:

var config = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<Source.Member, Target.Member>()
                .Include<Source.Property, Target.Property>()
                .Include<Source.Parameter, Target.Parameter>()
                .ForMember(t => t.Definition, opt => opt.MapFrom(s => Mapper.Map<Source.Class, Target.Class>((Source.Class)s.Definition)));

    cfg.CreateMap<Source.Property, Target.Property>();
    cfg.CreateMap<Source.Parameter, Target.Parameter>();
});
config.AssertConfigurationIsValid();
var mapper = config.CreateMapper();

var definitionLevel1 = new Source.Class();
definitionLevel1.Properties.Add(new Source.Property() { Name = "PropertyLevel_1.1" });
definitionLevel1.Properties.Add(new Source.Property() { Name = "PropertyLevel_1.2" });

var definitionLevel2 = new Source.Class();
definitionLevel2.Properties.Add(new Source.Property() { Name = "PropertyLevel_2.1" });
definitionLevel1.Definition = definitionLevel2;

Source.Member sourceMember = new Source.Property()
{
    Name = "Some_Property_Name",
    Definition = definitionLevel1,
    Type = typeof(CompositeType)
};

IEnumerable<Source.Member> sourceMembers = new List<Source.Member>() { sourceMember };
var targetMembers = mapper.Map<IEnumerable<Target.Member>>(sourceMembers);

请帮助我填补空白或缺失的部分。

4

1 回答 1

0

啊终于,我已经解决了这个复杂的问题,到目前为止结果似乎还不错,但是欢迎使用更好的实践(如果有的话)的建议,因为我是初学者并且刚刚开始使用 Automapper。

以下是各自映射器的配置。

配置:

IMapper memberMapper = null;
IMapper classMapper = null;

var classConfig = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<Source.Class, Target.Class>()
        .ForMember(t => t.Properties, opt => opt.MapFrom(s => memberMapper.Map<IList<Target.Property>>(s.Properties)))
        .ForMember(t => t.Definition, opt => opt.MapFrom(s => classMapper.Map<Source.Class, Target.Class>((Source.Class)s.Definition)));
    cfg.CreateMap<Source.Property, Target.Property>();
});
classConfig.AssertConfigurationIsValid();
classMapper = classConfig.CreateMapper();

var memberConfig = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<Source.Member, Target.Member>()
        .Include<Source.Property, Target.Property>()
        .Include<Source.Parameter, Target.Parameter>()
        .ForMember(t => t.Definition, opt => opt.MapFrom(s => classMapper.Map<Source.Class, Target.Class>((Source.Class)s.Definition)));

    cfg.CreateMap<Source.Property, Target.Property>();
    cfg.CreateMap<Source.Parameter, Target.Parameter>();
});
memberConfig.AssertConfigurationIsValid();
memberMapper = memberConfig.CreateMapper();

我使用的想法是两个映射器根据它​​们的范围一起工作以递归地完成此映射。

于 2016-05-03T21:02:50.410 回答