4

假设我有两个对象:

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填充,而不是Customeror Items。有没有办法进行递归翻译,或者唯一的选择是手动翻译客户和每个项目?

4

2 回答 2

5

我会将其包装在可重用的扩展方法中,例如:

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

wiki 上提供了更多 ServiceStack 的自动映射示例。

ServiceStack 的准则是,如果您的映射需要的不仅仅是从自动映射器推断出的默认常规行为,那么您应该将其包装在 DRY 扩展方法之后,以便您的映射所需的扩展和自定义可以清晰地表达并在代码中轻松维护。这被推荐用于 ServiceStack 中的许多事情,例如在代码中维护非常规和复杂的 IOC 绑定,而不是依赖于晦涩的重量级 IOC 特性。

如果你喜欢它,你当然可以采用像 AutoMapper 这样的 3rd 方工具。

于 2013-03-14T14:45:21.907 回答
3

您将不得不自己明确地处理复杂的映射。以下是来自 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}"));

我同意 Trust Me - 我是 Automapper 值得使用的医生。内置的翻译旨在减少依赖。

于 2013-03-14T13:57:44.777 回答