我正在使用.NET 4为客户创建一个小型客户端服务器应用程序。我应该创建一个实现许多合同的巨型服务(IInvoice,IPurchase,ISalesOrder等),还是应该创建许多服务,在许多端口上运行一个合同?我的问题特别感兴趣的是两种选择的优缺点。另外,回答这个问题的常用方法是什么?
我真正的困境是我没有做出这个决定的经验,而且我对wcf的经验不足以至于我需要帮助理解这个决定的技术含义。
答案 0 :(得分:5)
不要创建一个实现n个服务合同的大型服务。这些类型的服务很容易创建,但最终会成为一种维护问题,并且不能很好地扩展。另外,如果有一个开发小组竞争签到/签出,你会得到各种代码合并冲突。
也不要创建太多服务。避免使您的服务过于细化的陷阱。尝试基于功能创建服务。这些服务所暴露的方法也不应该是细粒度的。你做的更少的方法更少。通过创建GetUser(userObject用户),避免创建类似GetUserByID(int ID),GetUserByName(string Name)的函数。您将拥有更少的代码,更轻松的维护和更好的可发现性。
最后,无论你做什么,你可能只需要一个端口。
更新12/2018 自从我写这篇文章以来,事情发生了变化。现在有了微服务模式,我用chatty API创建了很多服务:)
答案 1 :(得分:2)
在实时应用程序中,每个实体都有一个服务合同,如Invoice,Purchase和SalesOrder将具有单独的ServiceContract
然而,对于每个服务合同,将使用netNamedPipeBinding或netTcpBinding通过Windows应用程序通过后台调用Invoice等异构客户端,同时客户端应用程序需要使用basicHttpBinding或wsHttpBindings来调用服务。基本上,您需要为每个服务创建多个端点。
答案 2 :(得分:2)
您通常会为每个主要实体创建不同的服务,例如IInvoice,IPurchase,ISalesOrder。
另一种选择是从命令中分离查询。您可以为每个主实体提供命令服务,并实现业务操作,仅接受他们执行操作所需的数据(避免类似CRUD的操作);和一个查询服务,以客户端所需的格式返回数据。这意味着命令部分使用底层域模型/业务层;而查询服务直接在数据库上运行(绕过业务,查询不需要)。这简化了您的查询并使其更加灵活(仅返回客户需要的内容)。
答案 3 :(得分:1)
似乎你在DataContract和ServiceContract之间混合。 您可以拥有一个ServiceContract和许多DataContract,这将完全满足您的需求。
答案 4 :(得分:0)
您应该根据预期的负载,所需的可扩展性和未来的视角来做出决定。当您为客户编写“小客户端服务器应用程序”时,它并没有明确了解手头开发的预期用途。必须考虑Big先生的答案。
欢迎您提出进一步的问题,并提供有关手头情况的具体数据或详情。感谢。
答案 5 :(得分:0)
事实是,拆分WCF服务 - 或任何服务是一种平衡行为。原则是你希望在考虑性能的同时保持复杂性的下行压力。
您创建的服务越多,您需要编写的配置就越多。此外,您将增加在客户端创建和维护所需的代理类的数量。
在一个服务上放置太多ServiceContracts会增加生成和使用代理所需的时间。但是,如果您最终只能在合同上执行一个或两个操作,那么您将增加系统的复杂性而几乎没有收获。这不是一个科学的处方,但一个好的经验法则可以说是每个ServiceContract大约10-20个OperationContracts。
类耦合当然是一个考虑因素,但你真的在处理不同的问题吗?这取决于你的系统做了什么,但是大多数系统只涉及一些关注的领域,所以拆分可能实际上并没有减少那么多的类耦合。
要记住的另一件事,这是非常重要的是始终使您的方法尽可能通用。出于某种原因,WCF在DataContracts中处理。 DataContracts意味着只要DataContracts已知,您就可以向服务器发送任何对象。
因此,例如,您可能有3个OperationContracts:
[OperationContract]
Person GetPerson(string id);
[OperationContract]
Dog GetDog(string id);
[OperationContract]
Cat GetCat(string id);
但是,只要这些都是已知类型,您就可以将它们合并到一个操作中,如:
[OperationContract]
IDatabaseRecord GetDatabaseRecord(string recordTypeName, string id);
最终,这是设计服务合同时最重要的考虑因素。如果您使用像序列化方法那样的DataContract序列化,这适用于REST。
最后,每隔几个月返回一次ServiceContracts并删除客户未使用的操作。这是另一个大问题!