【问题标题】:SOA architecture for ASP.NET with Entity Framework带有实体框架的 ASP.NET 的 SOA 架构
【发布时间】:2023-03-12 13:25:01
【问题描述】:

我正在重新设计解决方案的架构以实现SOA。

在进行了我想出的设计更改后:

  • MySolution.Client.MyProject.Web ...... //ASP.NET 网站
  • MySolution.Client.MyProject.Proxy .... //服务代理 C# 库项目 *1
  • MySolution.Service .................... //Service.svc 的Service.cs 在这里
  • MySolution.Service.DataContract ...... //IService.cs for Service.cs 在这里 *[2]
  • MySolution.Service.HttpHost .... //Service.svc 在这里
  • MySolution.Model ..................... //所有自定义数据类和 EDMX 模型都在这里 *[3]
  • MySolution.Repository ...... //Repository 使用 LINQ 和 ADO.NET 查询查询 DB

*1MySolution.Client.MyProject.Proxy: 该项目包含服务代理并包含表示类

*[2]MySolution.Service.DataContract:

  • 此项目包含 IService 和请求/响应类
  • Service.cs 中的所有方法都将 Request 类作为输入并返回 Response 类作为输出
  • 因此,该项目被 2 个客户端项目(Web 和代理)引用,因为它包含 IService 以及与 Service.cs 通信所需的所有请求/响应类

*[3]MySolution.Model: 该项目包含作为实体框架数据模型的 .edmx 以及项目中使用的一些自定义类。

问题:

因为我只使用请求/响应类在服务和客户端之间进行通信,所以 MySolution.Service.DataContract 项目只被 Service.cs 和 Repository.cs 使用

由于存储库生成的所有响应,我必须将它们映射到其各自响应类的属性(这使得原始返回的实体和响应类几乎相同)。但我没问题...

例如:

  • Repository.cs 方法中的 GetCustomer() 方法被 Service.cs 调用
  • 存储库中的 GetCustomer() 方法执行 LINQ 查询并返回“客户”对象
  • Service.cs 然后将“Customer”对象的所有属性映射到“CustomerResponse”对象
  • Service.cs 然后将“CustomerResponse”返回给调用者。

在这种情况下,大多数属性将在两个类中重复。如果有解决办法,那就好了,否则,我没问题。

然而,当 Repository.cs 的 GetCustomers() 方法(注意它不是 GetCustomer())被调用时,它会返回一个 Customer 对象的列表,并且为了返回目的而映射它意味着一个“ for 循环”,它迭代集合并进行映射...这不行...

考虑到我不想在没有“CustomerResponse”的情况下返回“Customer”对象,是否有更好的方法,因为首先它违反了 SOA 架构,其次我不希望我的客户项目有任何参考模型或存储库项目?

【问题讨论】:

    标签: asp.net wcf visual-studio-2008 entity-framework soa


    【解决方案1】:

    那么,您遇到问题的仅仅是映射吗?如果是这样,您可以查看一些开源映射库,例如 Mapper Extensions 或 AutoMapper,它们将自动执行任务。

    【讨论】:

    • 是的,主要问题是映射,另外,我必须创建完全相同的类来再次创建响应类;虽然这些类已经由实体框架生成......顺便说一下,从实体框架生成的类继承响应类是一种好方法吗?我不确定这是否会仅继承属性,或者会继承所有其他功能,例如当创建新对象并调用 Save 方法时,它会在 DB 中添加新行...... ???
    • 嗯,我想也许我应该明白你为什么在我回答之前首先使用响应对象......你只是想抽象物理数据结构吗?
    • 是的,在大多数情况下,但在其他情况下,我也添加了一些额外的属性功能
    • 从实体框架类继承可以正常工作,但是是的,您将获得所有功能。如果我是你,我会使用 POCO Entity T4 模板。这样,您的对象上下文与您的数据对象分离。然后,如果有意义,您可以从这些对象派生,或者在您的响应对象中实例化它们并通过属性公开它们。具有映射到响应对象和从响应对象映射的能力应该可以解决您的问题。 visualstudiogallery.msdn.microsoft.com/…
    • mmmm ......看起来不错......我会在周末尝试,如果卡住可能会回来......现在我认为它回答了这个问题。 (任何其他建议......关于我的架构??......因为这是我第一次实现 SOA......在阅读了“ASP.NET 设计模式”一书之后......只是为了让您了解更多关于架构:有 5 个客户端应用程序,它们通过各自的服务访问底层存储库/模型。
    【解决方案2】:

    如果您不喜欢实体和 DTO 之间的单独映射,请在您的存储库中公开 IQueryable 并使用对 DTO 的直接投影。缺点是这样的解决方案不能有效地进行单元测试。在这种情况下模拟存储库没有意义,因为再次模拟查询是 Linq-to-objects,而针对真实存储库的查询是 Linq-to-entities(仅在运行时才能看到差异的不同功能集)。

    顺便说一句。我在您的应用程序中没有看到太多 SOA - 我只看到多层应用程序。这就像在花园里种一棵树,然后说你有一片森林。此外,听起来您正在构建 CRUD 界面(实体与 DTO 几乎 1:1)。我有一种不好的感觉,你在不需要的架构上投入了太多的精力。如果您的主要目的是在数据库之上构建作为服务公开的 CRUD 操作,您可以直接公开实体,而且您可以使用像 WCF Data services 这样的工具。

    【讨论】:

    • 是的,在大多数情况下,实体与 DTO 是 1:1,但并非总是如此。可能你很老套,我不需要 SOA,但我仍然想实现它,因为我喜欢架构和客户端仅通过服务进行通信的方式。 Repository, Model 项目也被其他 4 个客户端应用程序使用,使用它们单独的服务,但所有 5 个客户端应用程序的底层 Repository 和 Model 都是相同的。
    • 这方面的最佳做法是什么?即(实体与 DTO 是 1:1),我应该再次创建相同的 DTO 类吗?
    • 5 服务公开相同的存储库?恕我直言,它更反对 SOA,然后公开实体本身。在 SOA 中,服务应该是独立的 = 服务之间没有共享功能(包括数据)。
    • 请阅读“BrandonZeider”帖子下的 cmets,如果您能提出一些很棒的建议,您可以在这里提出建议......
    • 如果你的实体是可序列化的,并且和你的DTO完全一样,你可以直接使用它。如果您不在服务和客户端之间共享合同组件,则不会违反 SOA,因为您的实体和 DTO 在 WSDL 中将被描述为相同的数据合同。
    【解决方案3】:

    听起来您的主要痛点是数据对象到data transfer objects (DTO) 的繁琐映射。我自己没有使用过这个,但似乎 AutoMapper 是用于以声明方式进行自动对象到对象映射的。

    我肯定会坚持将您的数据对象与您的服务中的数据合同分开。

    【讨论】:

    • 请看我在下面 BrandonZeider 的帖子上发表的评论
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-18
    • 2011-02-20
    • 2015-10-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-26
    • 1970-01-01
    相关资源
    最近更新 更多