2012-04-24 58 views
6

我有一个WCF服务,并刚刚为业务对象创建了一个DTO。数据传输对象 - 在DTO中执行映射还是在业务对象中执行映射?

我的问题是在哪里把两者之间的映射?

A)在DTO中?

public class PersonDTO 
{ 
    [DataMember] public string Id    { get; set; } 
    [DataMember] public string Name   { get; set; } 

    public void CloneFrom(Person p) 
    { 
     Id = p.Id; 
     Name = p.Name; 
    } 

    public void Populate(Person p) 
    { 
     p.Id = Id; 
     p.Name = Name; 
    } 
} 

B)在业务对象?

public class Person 
{ 
    public string Id    { get; set; } 
    public string Name   { get; set; } 

    public void CloneFrom(PersonDTO dto) 
    { 
     Id = dto.Id; 
     Name = dto.Name; 
    } 

    public PersonDTO GetDTO() 
    { 
     return new PersonDTO() 
     { 
      Id = Id; 
      Name = Name; 
     } 
    } 
} 

我喜欢的涉及在分离(业务对象没有DTO的知识),但我更喜欢B的封装(无需公开业务对象胆量DTO)。

只是想知道是否有一个标准的方式?

回答

11

我倒是觉得这需要一个单独的类,因为无论是BO也不DTO应与它们转化为另一个类有关。

我个人使用的对象变换的automapper库。通过简单的转换,就像在你的例子中那样,映射是在一行代码中完成的,复杂的转换也很容易设置。

如果要映射你自己,你仍然可以使用扩展方法,不断从你的DTO和BO类分开的映射实现。

+0

真的吗?如果我打算公开我的业务对象以允许第三类进行映射,那么我最好在DTO中做这件事。创建另一个类似乎对我来说太过于矫枉过正。不过,我会看看automapper,谢谢。 – GazTheDestroyer 2012-04-24 14:12:53

+4

@GazTheDestroyer:DTO的意思是数据传输不转换。 DTO并不知道它的用法,即:映射。它传输数据,消费者可以使用这些数据实现任何目的,例如:将其映射到ViewModel。您可以自由地将映射添加到DTO,但在我的愚见中,这意味着尽管您错过了DTO的预期目的,因此您的DTO不再是DTO。在我们当前的项目中,存储库会生成实体BL接收实体,将它们映射到DTO。 UI层查询BL,获取DTO并将它们映射到ViewModels(根据需要)。 – Nope 2012-04-27 22:33:50

1

我会建议一个组件层。它应该负责任地在业务层和数据层之间进行通信。在这种情况下,您可以使用它将您的DTO对象转换为Business Objects。

+0

根据我的经验,而NetTiers有一些很好的素质,实际上它的工作可能是令人沮丧的,看到http://stackoverflow.com/questions/8220206/whither-nettiers – 2013-11-17 22:55:00

+0

@DavidClarke我参考,主要是刚刚的定义一个组件层。我提供的链接已损坏,因此我将删除。 :) – Khan 2013-11-19 03:32:53

0

你关注“没必要公开业务对象胆量DTO”似乎有点杞人忧天,除非有你是不是在你的代码显示,因为您正在访问的公共属性,即没有胆量在所有的东西。

顺便说一句,而不必克隆方法,你可以实现一个投操盘手:MSDN

这样,你可以这样做: 人员P =(人)myPersonDTO;

+0

是的,我的例子很简单。实际上,我的业务对象具有私人内容,我并不想公开它们用于映射目的。 – GazTheDestroyer 2012-04-24 14:09:21

+1

如果BO上的东西被定义为private/protected,那么使用它的任何东西都不会看到它,所以不知道这个问题会出现在那个方面。 – Peter 2012-05-01 14:09:14