我在一个程序集中有一个类型TestResult,这个程序集由两个应用程序使用。我还有一个托管在一个应用程序(Win Service)中的WCF服务,它公开了一个返回此TestResult类型实例的方法。
虽然这样可行,但只考虑返回数据联系类型会被认为是一种好习惯吗?未来可能还有其他应用程序可能需要使用此服务,我希望不再需要使用应用程序发送DLL,以便它可以使用该服务。
答案 0 :(得分:2)
DataContracts(有时候是他们的诅咒)的美妙之处在于,VS可以创建一个能够实现DataContract的对象,而无需公开实现。所以,如果你不想发送DLL,那很好;当您的服务的使用者添加服务引用时,VS会创建自己的TestResults对象,该对象实现ITestResults并为DataMembers定义访问者。
请注意,由于这种行为,最好使DataContract实现“贫血”;您无法定义将传递给生成的实现的业务逻辑,因此通常最好将它们设置为仅包含字段或简单属性。这样,您的服务就不会假设任何生成的类在另一方面能够做什么。
编辑:如果作为ServiceContract的类或接口公开了将TestResult作为OperationContract返回的方法,则TestResult必须是DataContract,并且任何感兴趣的属性或字段必须是DataMembers。这不是最佳实践,需要平坦。在硬币的另一面,无论方法在服务器端代码中的可见性如何,如果该方法不是OperationContract,那么它对客户端是不可见的,并且TestResult不必是DataContract,而不是其他一些OperationContract方法接受或返回TestResult的实例。
您已声明您作为服务电话的结果返回了TestResult。实际上,它听起来像是您的OperationContract返回一个看起来就像TestResult的DataContract类,并且您将返回TestResult。这表明在TestResult和TestResultDataContract之间指定了隐式转换,或者在更高级别中将某些行为克隆到TestResultDataContract中。没关系;转换发生在返回之前,DataContract仍然是实际来自服务方法的内容。如果从指定返回TestResultDataContract类型的方法返回TestResult,您可能希望记录发生的情况。
另一种可能性是,你并没有真正通过生成的客户端代理将服务作为远程WCF服务进行调用;您只是实例化并调用实际实现该服务的类。我见过很多次;所需要的只是对实现类而不是代理的引用,并向你在dev中看不到的生产环境中的bug问好。如果您真的使用客户端代理,那么在客户端代码中引用相同的TestResult实现(或其DataContract装饰的兄弟)是完全正确的,前提是您可以访问包含客户端上该合同的DLL。但是,重点是,这不是必要的;如果您没有与服务的DataContract签名匹配的对象,则会为您创建一个。
答案 1 :(得分:0)
也许我误解了,但听起来你应该将TestResult定义为DataContract,并继续正常地从服务操作中返回该类型。对于可以访问类型(DLL)的二进制表示的应用程序,它们可以引用该DLL并以与今天相同的方式使用该服务。
对于将来不可能(或实际)使用DataContract的二进制表示的未来用例,您可以公开MEX端点(和/或使用serviceMetadata行为),以允许消费者构建他们的自己的DataContract副本。此过程的一个示例是“添加服务引用” - 这会吸收服务的元数据,并构建DataContracts的本地副本等。
是的,我认为服务的最佳做法是仅公开/使用已定义的DataContracts或本机类型(如字符串)。