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

时间:2013-09-10 19:53:53

标签: c# wcf entity-framework domain-driven-design

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

我的新结构如下:

客户:
Reporting.Silverlight = Silverlight应用程序。这将参考我的DTO课程 Reporting.Web =拥有我的SL应用程序,是人们进入它的主要切入点。

业务:
Reporting.Services =我的WCF服务就在这里。我的SL应用程序将调用此方法来执行操作,这些服务将返回DTO类 Reporting.Services.Contracts =保存我的WCF服务接口,并包含带有DataContract装饰器的DTO类。
Reporting.Domain =保存我的域对象和业务逻辑

数据:
Reporting.Data.Contract =保存我的存储库& amp;工作单位
Reporting.Data =存储库/ UoW的具体实现。此处定义了Entity Framework 5上下文。
Reporting.Data.Models =保存我的所有Entity对象,以便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客户端的一堆属性。我的DTO属性的绝大多数都映射到我的实体对象1:1的特性,除了ID字段。这是我的Entity对象,与上面的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

中的第3个几乎相同的类
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实体类中是个好主意,那么在结构上我应该将该程序集移动到我的业务层和数据层之外,即使这些对象是保存到我的数据库的对象?理想情况下,我试图在我的数据项目中和业务项目之外保留对Entity Framework的任何引用。我有大约200个左右的类,我正在移植并将构成我的域,并且我希望一旦我完成重写,这个东西可以扩展到更多的功能。任何关于如何构建这个东西并保持干燥的见解都将非常感激。

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

1 个答案:

答案 0 :(得分:22)

  

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

IMO他们不是“3个几乎相同的班级”,他们没有达到同样的目的。它们是相同领域概念的多个方面,每个方面都针对特定层的需求而定制。

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

关于此问题的一篇好文章:http://blog.ploeh.dk/2012/02/09/IsLayeringWorththeMapping/