21

我正在重新设计我当前的项目以使其更易于维护,并尽我所能遵循良好的设计实践。目前,我有一个带有 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 = 保存我的存储库接口和工作单元
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 字段除外。这是与上述 DTO 对应的我的 Entity 对象:

[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 个要移植的类,它们将构成我的域,我希望一旦我完成重写,这个东西可以扩展到更多的功能。

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

4

1 回答 1

26

拥有 3 个几乎相同的课程不可能是解决这个问题的正确方法,不是吗?

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

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

一篇很好的文章:http ://blog.ploeh.dk/2012/02/09/IsLayeringWorththeMapping/

于 2013-09-11T09:55:23.177 回答