如何减少域/实体/DTO 对象的重复

本文关键字:对象 实体 何减少 DTO | 更新日期: 2023-09-27 18:30:54

我正在重新设计我当前的项目,使其更易于维护,并尽最大努力遵循良好的设计实践。目前,我有一个带有 Silverlight 组件的解决方案,该 SL 应用程序的 ASP.Net 主机,该主机还包含 WCF RIA 服务和共享类库,以便 SL 和 WCF 服务都可以共享对象。业务逻辑分散在各处,所有 CRUD 操作都在我的 WCF 服务中手动编码。因此,我正在为所有内容创建一个新结构,并将这种混乱移植到新格式中。在这样做的过程中,我发现我在重复课程,而我不知道我是否应该这样做。

我的新结构是这样的:

客户:
Reporting.Silverlight = Silverlight Application。这将引用我的 DTO 类。
Reporting.Web = 保存我的 SL 应用程序,是人们访问它的主要入口点。

商:
Reporting.Services = My WCF Services 位于此处。我的 SL 应用程序将调用它来执行操作,这些服务将返回 DTO 类。
Reporting.Services.Contract = 保存 WCF 服务的接口,并包含带有 DataContract 修饰器的 DTO 类。
Reporting.Domain = 保存我的域对象和业务逻辑

数据:
Reporting.Data.Contract = 保存我的存储库和工作
单元接口Reporting.Data = 存储库/UoW 的具体实施。此处定义了实体框架 5 上下文。
Reporting.Data.Models = 保存我所有的实体对象,以便 EF5 可以使用 SQL 执行其操作。

我有 3 个地方,我的班级几乎完全相同,对我来说它闻起来很香。在Reporting.Services.Contracts内部,我有一个DTO,可以交给SL客户端。下面是一个示例:

[DataContract(Name = "ComputerDTO")]
public class ComputerDTO
{
    [DataMember(Name = "Hostname")]
    public string Hostname { get; set; }
    [DataMember(Name = "ServiceTag")]
    public string ServiceTag { get; set; }
  // ... lots more
}

我认为上面的DTO很好,因为它只是一堆传递给SL客户端的属性。除 ID 字段外,我的绝大多数 DTO 属性都 1:1 映射到我的实体对象的属性。这是我与上述 DTO 对应的实体对象:

[Table("Inventory_Base")]
public class ComputerEntity
{
    // primary key
    [Key]
    public int AssetID { get; set; }
    // foreign keys
    public int? ClientID { get; set; }
    // these props are fine without custom mapping
    public string Hostname { get; set; }
    public string ServiceTag { get; set; }
    // ... plus a bunch more in addition to my navigation properties
}

我在 EF5 中使用代码优先方法。我仍处于重写的最初阶段,到目前为止,我的印象是业务逻辑不应该在我的 EF 实体中。DTO也不应该有业务逻辑。这意味着它会进入我的领域模型,对吧?好吧,这给了我在Reporting.Domain中几乎相同的第三门课

public class Computer
{
   public string Hostname { get; set; }
   public string ServiceTag { get; set; }
   // ... lots more, pretty much mirrors the DTO
   public string Method1(string param1)
   {
       // lots of methods and logic go in here
   }
}

拥有 3 个几乎相同的类不可能是解决这个问题的正确方法,不是吗?我是否应该将所有业务逻辑放在 EF 实体中,然后将结果投影到通过网络传递的 DTO 中?如果最好将所有域/业务逻辑塞进 EF 实体类中,那么从结构上讲,我是否应该将该程序集移动到业务层和数据层之外,即使这些对象是保存到数据库的对象?理想情况下,我尝试保留对数据项目和业务项目外部的实体框架的任何引用。我有大约 200 个左右的类,我正在移植这些类,并将构成我的域,我希望一旦我完成重写,这个东西就会扩展到更多的功能。任何关于如何构建这个东西并保持干燥的见解将不胜感激。

如果它有助于定义我想要做得更好的地方,请告诉我是否应该包括我正在遵循的存储库/工作单元方法。

如何减少域/实体/DTO 对象的重复

拥有 3 个几乎相同的类不可能是正确的方法 去吧,可以吗?

IMO 它们不是"3 个几乎相同的类",它们的目的不同。它们是同一领域概念的多个方面,每个方面都是针对特定层的需求量身定制的。

这是模块化和明确关注点分离的代价。您拥有的端口越多(如Hexagonal Architecture的端口和适配器),您需要的方面就越多,并且需要做的映射就越多。

关于这个的一篇好文章:http://blog.ploeh.dk/2012/02/09/IsLayeringWorththeMapping/