2016-05-03 68 views
0

私はこれらのクラスを2つの異なる名前空間、 SourceおよびTargetAutomapperを使用して複雑なネストされたオブジェクト階層を変換する方法

マッピングクラス:Instanceクラスは、ネストされた階層がNレベルまでここからスタートしますので、Classの参照を保持するタイプのオブジェクトのDefinition性質を持っていることを

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 
{ 
} 

注意。私はうまくいきましたが、Class内のDefinitionプロパティとそのネストされた階層オブジェクトは、TargetではなくSourceの参照を保持していました。何らかの形でこの変換作業を行うために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); 

隙間や欠落部分を埋める私を支援してください。

答えて

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(); 

私が使用しているアイデアは、2つのマッパーは、このマッピングは再帰的に行わ取得し、その範囲ごとに一緒に働いているということです。

+0

'定義'オブジェクトがすべてのレベルにわたって同じオブジェクト参照を保持しているときに、あるシナリオでは、これが起こっているので、これは不完全な解決策です。 'ForMember(t => t。定義、opt => opt.MapFrom(s => classMapper.Map ((Source.Class)s.Definition))) ' –

関連する問題