wcf 决策:一项服务多项合同或多项服务

Posted

技术标签:

【中文标题】wcf 决策:一项服务多项合同或多项服务【英文标题】:wcf decision: one service multiple contracts or many services 【发布时间】:2013-06-29 18:00:07 【问题描述】:

我正在使用 .NET 4 为客户创建一个小型客户端服务器应用程序。我应该创建一个实现许多合同(IInvoice、IPurchase、ISalesOrder 等)的巨型服务,还是应该创建多个服务,每个服务在多个端口上运行一个合同?我的问题特别对任何一种选择的利弊感兴趣。另外,回答这个问题的常用方法是什么?

我真正的困境是我没有做出这个决定的经验,而且我对 wcf 的经验也很少,我需要帮助来理解这样一个决定的技术含义。

【问题讨论】:

【参考方案1】:

不要创建一个大型服务来实现 n 数量的服务合同。这些类型的服务很容易创建,但最终会成为维护方面的难题,并且无法很好地扩展。另外,如果有开发组竞争签入/签出,您将遇到各种代码合并冲突。

也不要创建太多服务。避免使您的服务过于细化的陷阱。尝试基于功能创建服务。这些服务公开的方法也不应该是细粒度的。你最好用更少的方法做更多的事情。通过创建 GetUser(userObject user) 避免创建类似的函数,如 GetUserByID(int ID)、GetUserByName(string Name)。您将拥有更少的代码、更容易的维护和更好的可发现性。

最后,无论您做什么,都可能只需要一个端口。

2018 年 12 月更新 有趣的是,自从我写这篇文章以来事情发生了怎样的变化。现在有了微服务模式,我正在使用聊天 API 创建很多服务 :)

【讨论】:

如果使用部分类/接口文件来避免合并冲突,那么“不会很好地扩展”的说法呢?这在技术上意味着什么? @Askolein...这意味着,如果您在单个合约中塞入太多内容,则可能会成为性能瓶颈以及维护/可扩展性难题。 感谢您的回答,但我的问题更多是“为什么”可能是性能问题,而不是“什么”是性能问题。你说“瓶颈”:我知道在 ISS/WCF 中每个 Web 请求都是一个新的 Service 实例。一个大服务上的多个请求仍然是多个实例,而不是一个实例服务所有这些实例。所以没有缩放问题。这个推理对吗? @Askolein...如果某些方法比其他方法更占用资源,它们可能会对其他方法和整个服务产生负面的性能影响。当考虑到单独的服务合同/网站时,这种风险很容易处理。【参考方案2】:

您通常会为每个主要实体(如 IInvoice、IPurchase、ISalesOrder)创建不同的服务。

另一种选择是将查询与命令分开。您可以为每个主要实体提供一个命令服务,并实施业务操作,只接受他们执行操作所需的数据(避免类似 CRUD 的操作);以及一个以客户端所需格式返回数据的查询服务。这意味着命令部分使用了底层的领域模型/业务层;而查询服务直接对数据库进行操作(绕过业务,查询不需要)。这大大简化了您的查询并使其更加灵活(仅返回客户需要的内容)。

【讨论】:

【参考方案3】:

在实时应用程序中,每个实体都有一份服务合同,例如 Invoice、Purchase 和 SalesOrder 将有单独的 ServiceContract

但是,对于每个服务合同,后台办公室将使用 netNamedPipeBinding 或 netTcpBinding 通过 Windows 应用程序调用 Invoice 等异构客户端,同时客户端应用程序需要使用 basicHttpBinding 或 wsHttpBindings 调用服务。基本上你需要为每个服务创建多个端点。

【讨论】:

【参考方案4】:

您似乎在 DataContract(s) 和 ServiceContract(s) 之间混用。 您可以拥有一个 ServiceContract 和多个 DataContract,这将完全满足您的需求。

【讨论】:

【参考方案5】:

事实上,拆分 WCF 服务或任何服务是一种平衡行为。原则是您希望在仍然考虑性能的同时保持对复杂性的向下压力。

您创建的服务越多,您需要编写的配置就越多。此外,您将增加需要在客户端创建和维护的代理类的数量。

在一项服务上放置过多的 ServiceContract 会增加生成和使用代理所需的时间。但是,如果您最终只在合同上执行一两个操作,那么您将增加系统的复杂性而几乎没有什么收获。这不是一个科学的处方,但一个好的经验法则可以说是每个 ServiceContract 大约 10-20 个 OperationContract。

类耦合当然是一个考虑因素,但你真的在处理单独的问题吗?这取决于您的系统的功能,但大多数系统只处理少数几个问题,因此拆分可能实际上并不会减少类耦合。

要记住的另一件事,也是非常重要的一点是始终使您的方法尽可能通用。 WCF 处理 DataContracts 是有原因的。 DataContracts 意味着只要 DataContracts 已知,您就可以向服务器发送任何对象或从服务器发送任何对象。

因此,例如,您可能有 3 个 OperationContract:

[OperationContract]
Person GetPerson(string id);

[OperationContract]
Dog GetDog(string id);

[OperationContract]
Cat GetCat(string id);

但是,只要这些都是已知类型,您就可以将它们合并到一个操作中,例如:

[OperationContract]
IDatabaseRecord GetDatabaseRecord(string recordTypeName, string id);

最终,这是设计服务合同时要考虑的最重要的事情。如果您使用 DataContract 序列化之类的序列化方法,这适用于 REST。

最后,每隔几个月回顾一下您的 ServiceContract,并删除客户未使用的操作。这又是一件大事!

【讨论】:

【参考方案6】:

您应该根据预期的负载、所需的可扩展性和对未来的展望来做出决定。当您为客户编写“小型客户端服务器应用程序”时,它并没有明确说明手头开发的预期用途。大先生的回答也必须考虑。

非常欢迎您提出进一步的问题,并附上有关当前情况的具体数据或细节。谢谢。

【讨论】:

以上是关于wcf 决策:一项服务多项合同或多项服务的主要内容,如果未能解决你的问题,请参考以下文章

HTTP动词

HTTP动词

Restful架构特点

如何将空中附加服务添加到 UpdateReservationRQ

http的常用动词

WCF - 使用完全相同的数据合同的多个服务合同