在使用(非静态)AutoMapper实例时,如何展平嵌套类?

时间:2017-09-21 14:20:02

标签: c# automapper

我正在尝试使用AutoMapper(v6.1.1)来展平包含更多嵌套类的类。

对于原因™我无法更改这些类,因此无法更改名称。

记住这一点我可以使用静态Mapper来解决它:

// This is the nested user, it has a further nested class
public class NestedUser
{
    public long id { get; set; }
    public string type { get; set; }
    public Attributes attributes { get; set; }
}

public class Attributes
{
    public string first_name { get; set; }
    public string last_name { get; set; }
    public string name { get; set; }
}

// This is the flattened representation
public class FlattenedUser
{
    public long id { get; set; }
    public string type { get; set; }
    public string first_name { get; set; }
    public string last_name { get; set; }
    public string name { get; set; }
}

// Create a nested user
var nested = new NestedUser
{
    id = 1,
    type = "Contact",
    attributes = new Attributes
    {
        first_name = "Equals",
        last_name = "Kay",
        name = "Equalsk"
    }
};

// Use the static Mapper to flatten
Mapper.Initialize(cfg =>
{
    cfg.CreateMap<Attributes, FlattenedUser>(MemberList.None);
    cfg.CreateMap<NestedUser, FlattenedUser>(MemberList.None)
       .ConstructUsing(s => Mapper.Map<FlattenedUser>(s.attributes));
});

Mapper.AssertConfigurationIsValid();

var flattened = Mapper.Map<FlattenedUser>(nested);

对象flattened现在已正确填充其所有属性。

更多原因™我想使用AutoMapper的实例,如下所示:

var config = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<Attributes, FlattenedUser>(MemberList.None);
    cfg.CreateMap<NestedUser, FlattenedUser>(MemberList.None)
       .ConstructUsing(s => Mapper.Map<FlattenedUser>(s.attributes));
});

config.AssertConfigurationIsValid();

var flattened = config.CreateMapper().Map<FlattenedUser>(nested);

我的问题是行.ConstructUsing(s => ... ));,它引用了静态Mapper,因此抛出了运行时异常:

  

System.InvalidOperationException :'Mapper未初始化。使用适当的配置调用Initialize。如果您尝试通过容器或其他方式使用映射器实例,请确保您没有对静态Mapper.Map方法的任何调用,并且如果您使用的是ProjectTo或UseAsDataSource扩展方法,请确保传入适当的IConfigurationProvider实例“。

我不想对每个嵌套属性使用.ForMember(...),因为它会破坏我正在尝试的对象。

现在我被卡住了。 是否可以使用AutoMapper实例而不是静态方式来展平嵌套类?

1 个答案:

答案 0 :(得分:3)

我看到了两个解决问题的方法,具体取决于你应该适合的情况:

首先:如果要继续对嵌套对象使用静态映射器,则必须将嵌套对象的注册移动到静态配置:

Mapper.Initialize(cfg=> cfg.CreateMap<Attributes, FlattenedUser>(MemberList.None));

var config = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<NestedUser, FlattenedUser>(MemberList.None)
        .ConstructUsing(s => Mapper.Map<FlattenedUser>(s.attributes));
});

第二:使用ResolutionContext

var config = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<Attributes, FlattenedUser>(MemberList.None);
    cfg.CreateMap<NestedUser, FlattenedUser>(MemberList.None)
        .ConstructUsing((s, r) => r.Mapper.Map<FlattenedUser>(s.attributes));
});