【问题标题】:How can I flatten a nested class when using an instance of (not static) AutoMapper?使用(非静态)AutoMapper 的实例时如何展平嵌套类?
【发布时间】:2018-03-02 22:51:34
【问题描述】:

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

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

考虑到这一点,我可以像这样使用静态映射器来解决它:

// 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 =&gt; ... )); 行,它指的是静态映射器,因此它会引发运行时异常:

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

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

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

【问题讨论】:

    标签: c# automapper


    【解决方案1】:

    我看到了 2 个解决问题的选项,具体取决于您的情况:

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

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

    【讨论】:

    • ResolutionContext 是拼图中缺失的部分,谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-23
    • 1970-01-01
    • 2020-04-15
    • 1970-01-01
    • 1970-01-01
    • 2016-11-26
    相关资源
    最近更新 更多