DTO模式的策略 - 每个实体的多个DTO还是只有一个?

时间:2013-03-14 01:28:07

标签: asp.net design-patterns web-applications dto

我正在使用DTO构建我的第一个应用程序 - 我目前有一个用于获取特定对象数据的DTO,以及另一个用于更新(PUTting)数据的不同DTO - 因为只有少数字段可以从任何客户端更新,我决定为PUTting创建一个专用的DTO,以避免通过线路发送不必要的数据/字段。这是可维护性方面的良好做法,还是某种禁忌?

4 个答案:

答案 0 :(得分:1)

对于多个操作使用相同类型我没有问题。也许你有多个GET,它们为类似的目的返回类似的数据。在这种情况下,没有理由不能重复使用相同的类型。

但是,您已经确定您的GET和PUT操作需要不同的数据。因此,它们不仅是不同的操作,而且还需要不同的数据。

+----------------+-------------------+--------------------------+
| Similar Data   | Similar Purpose   | Try to Reuse             |
| Similar Data   | Different Purpose | Consider; is it logical? |
| Different Data | Similar Purpose   | New Type                 |
| Different Data | Different Purpose | New Type                 |
+----------------+-------------------+--------------------------+

创建新的DTO以满足特定需求还有其他好处,例如:

  • 不要让开发人员感到困惑(即使那是你!)
  • 没有打开安全漏洞,因此填充了不打算使用的字段

为了更容易:

  • 接口可用于帮助强制类型之间的公共字段。
  • ASP.Net Web API(不确定您是否使用了您的问题)强烈支持dynamic inputs。这可以消除对DTO的需求(尽管以较少的编译时类型检查为代价)。

答案 1 :(得分:0)

这是一个选择问题。我习惯使用orm mappers来减少代码。我发现花时间预先定义保存并使用一个dto类可以实现更好的可伸缩性和可维护性,即使这意味着所有字段都会更新。有边缘情况。如果表使用具有大量blob类型数据的字段,那么您可能应该以某种方式对这些更新进行子类化。这是一个意见问题。

答案 2 :(得分:0)

我确实为每个实体使用多个DTO。但是,我甚至经常没有为视图预先定义DTO,我只是创建一个匿名类实例,它是使用Linq的实体投影并将其绑定到GUI。

E.g。显示用户列表

var users = ... // fetch from DB
ViewData["users"] = users.Select( u => new { Id = u.Id, Name = u.First + " " + u.Last});

显示得分板:

var users = ... // fetch from DB
ViewData["users"] = users.Select( u => new { Id = u.Id, Name = u.Last, Score = u.Score});

这使我免于创建2个不同的DTO。一个潜在的缺点是视图不是强类型的,因此根据ASP.NET MVC的版本,我需要将视图模型声明为dynamic或使用一些ExpandoObject技巧,但它们都被很好地隐藏了。 / p>

但是,我总是创建DTO来修改状态并将它们视为命令。我通常对实体的不同操作有不同的DTO,例如ChangeUserAddressDTOChangeUserLevelDTO

答案 3 :(得分:-2)

它不是禁止 - 否则使用相同的DTO进行CRUD将使其在长期运行中更易于维护。稍后,如果添加和删除新字段,您可能必须更改所有图层中的代码。您永远不知道客户何时改变主意来编辑更多或更少的数据。