我觉得我已经过去使用DTO过度复杂了我的设计,但我正在寻找第二意见。
我的结构是:
因此,PlaylistItem域对象如下所示:
public class PlaylistItem
{
public virtual Guid Id { get; set; }
public virtual Playlist Playlist { get; set; }
public virtual int Sequence { get; set; }
public virtual string Title { get; set; }
public virtual Video Video { get; set; }
// Not written to the database. Used for client to tell who is who after a save.
public virtual string Cid { get; set; }
}
和PlaylistItem DTO看起来像:
[DataContract]
public class PlaylistItemDto
{
[DataMember(Name = "playlistId")]
public Guid PlaylistId { get; set; }
[DataMember(Name = "id")]
public Guid Id { get; set; }
[DataMember(Name = "sequence")]
public int Sequence { get; set; }
[DataMember(Name = "title")]
public string Title { get; set; }
[DataMember(Name = "video")]
public VideoDto Video { get; set; }
[DataMember(Name = "cid")]
public string Cid { get; set; }
}
唯一的变化是我通过用PlaylistId替换播放列表引用来打破循环引用结构。
C#.NET MVC中的默认JSON序列化程序无法处理循环结构。我已经更新到使用能够处理循环结构的JSON.NET序列化器。我现在正在重新评估为什么我甚至需要我的DTO。
在这里我应该注意/考虑DTO是否有任何好处?将JSON化循环引用并通过网络发送是不好的做法吗?
答案 0 :(得分:2)
作为分层格式的JSON在以分层方式表示数据时将发挥最佳作用。 JSON不是一个节点图,因此我认为尝试序列化类图数据将会很困难。我认为您将对象(Playlist
)转换为“引用”(PlaylistId
)形式的解决方案是正确的。接收和处理此JSON的代码可以在必要时重新构建循环引用,因为您已准备好“外键”(PlaylistId
)。
大多数时候,我宁愿有一个额外的DTO而不是没有。 DTO将您与变更隔离开来 - 在这种情况下,将您的 API 与变更隔离开来。 PlaylistId
不太可能在将来更改其架构,但实际的Playlist
可能会更改。
答案 1 :(得分:2)
在这里我应该注意/考虑DTO是否有任何好处?
设计。这是一个公共API,你想确保它是黑貂,而内部对象是/可以改变而不需要大量的审查。如果这是一个“服务器外”样式的界面,并且您不希望每次进行微小更改时都强制进行API更新(客户端更新),那么数据类型的更改就会出现问题。
因此,单独定义API级别定义对象(DTO)有助于这部分不更改公共接口。