如何在ServiceStack中转换复杂对象?

本文关键字:复杂 对象 转换 ServiceStack | 更新日期: 2023-09-27 18:03:47

假设我有两个对象:

class Order
{
    string Name {get; set;}
    Customer Customer {get; set;}
    Item[] Items {get; set;}
}

class OrderDTO
{
    string Name {get; set;}
    CustomerDTO Customer {get; set;}
    ItemDTO[] Items {get; set;}
}

如果我收到一个完全填充的对象orderDTO,并执行orderDTO.TranslateTo<Order>(),结果将只填充Name,而不是CustomerItems。是否有递归翻译的方法,或者唯一的选择是手动翻译Customer和每个item ?

如何在ServiceStack中转换复杂对象?

我会用一个可重用的扩展方法来封装它,例如:

public static OrderDTO ToDto(this Order from)
{
    return new OrderDTO { 
        Name = from.Name,
        Customer = from.ConvertTo<CustomerDTO>(),
        Items = from.Items.Map(x => x.ConvertTo<ItemDTO>()).ToArray(),
    }
}

可以在需要映射到Order DTO时调用,例如:

return order.ToDto();

关于ServiceStack的自动映射的更多例子可以在wiki上找到。

ServiceStack的路线是,如果你的映射需要比从自动映射器推断的默认常规行为更多的行为,那么你应该把它包装在DRY扩展方法后面,这样你的映射所需的扩展和自定义就可以在代码中清晰地表达和维护。对于ServiceStack中的许多事情,都建议这样做,例如,在代码中维护非常规和复杂的IOC绑定,而不是依赖于晦涩的重量级IOC功能。

如果你喜欢,你当然可以采用第三方工具,如AutoMapper。

您将不得不自己显式地处理复杂的映射。下面是一些来自ServiceStack src的单元测试,它们展示了当前如何处理复杂类型。

可以看到,Car对象被序列化为JSON。

var user = new User() {
    FirstName = "Demis",
    LastName = "Bellot",
    Car = new Car() { Name = "BMW X6", Age = 3 }
};
var userDto = user.TranslateTo<UserDto>();
Assert.That(userDto.FirstName, Is.EqualTo(user.FirstName));
Assert.That(userDto.LastName, Is.EqualTo(user.LastName));
Assert.That(userDto.Car, Is.EqualTo("{Name:BMW X6,Age:3}"));

我同意相信我-我是一个医生Automapper值得使用。内置的翻译是为了减少依赖而设计的。