2011-03-30 47 views
1

我在程序集中有一个类型TestResult,此程序集由两个应用程序使用。我还有一个WCF服务托管在一个应用程序(Win Service)中,该应用程序公开了一个返回此TestResult类型实例的方法。使用WCF中的数据合同返回共享类型

虽然这种方法有效,但只有返回数据联系人类型才算是好的做法吗?未来可能还有其他应用程序可能需要使用此服务,并且我理想的情况是不需要将DLL发布到应用程序中,以便它可以使用该服务。

回答

2

DataContracts(有时是他们的诅咒)的美妙之处在于VS可以创建一个将满足DataContract的对象,而无需公开您的实现。所以,如果你不想运送DLL,那就好了;当服务的使用者添加服务引用时,VS会创建自己的TestResults对象,该对象实现ITestResults并为DataMembers定义访问者。

请注意,由于这种行为,最好使DataContract实现“贫血”;您无法定义将传递给生成的实现的业务逻辑,因此通常最好将其设置为仅包含字段或简单属性。这样,你的服务就不会假设任何生成的类可以在另一方做什么。

编辑:如果类或接口是的ServiceContract暴露了返回的TestResult作为OperationContract的方法中,然后TestResult中必须是一个DataContract和任何属性或感兴趣的字段必须是数据成员。这不是最佳做法,它是平坦的要求。另一方面,无论服务器端代码中该方法的可见性如何,如果该方法不是OperationContract,那么它对客户端不可见,并且TestResult不必是DataContract,除非其他OperationContract方法接受或返回TestResult的一个实例。

您已经声明您作为服务调用的结果返回TestResult。实际上,它听起来像是你的OperationContract返回一个DataContract类,它看起来就像一个TestResult,并且你正在返回TestResult。这表明在TestResult和TestResultDataContract之间指定了隐式转换,或者在更高级别中将TestResult克隆到TestResultDataContract中的某些行为。没关系;转换发生在返回之前,并且DataContract仍然是服务方法实际出现的内容。如果您从方法返回TestResult,并指定返回TestResultDataContract类型,您可能需要记录发生了什么。

另一种可能性是您没有真正通过生成的客户端代理将该服务作为远程WCF服务调用;你只是实例化并调用实际实现该服务的类。我见过很多次,所需要的只是对实现类的引用,而不是对代理的引用,并向生产环境中的错误发问,而这些错误在dev中没有看到。假如您真的使用客户端代理,那么在客户端代码中引用相同的TestResult实现(或其DataContract-decorated兄弟)是完全正确的,前提是您可以访问包含该客户端合同的DLL。但是,重要的是这不是必要的;如果您没有与服务的DataContract签名匹配的对象,则会为您创建一个。

+0

TestResult类型没有任何DataContract或DataMember属性,它不是在客户端创建的。相反,客户端上方法的返回类型只是使用完整的名称空间和类型名称来引用该类型。 TestResult类型用在WCF服务下面,它只是不是创建DataContract类型,而是与TestResult类型相同,我只是返回一个TestResult。 – Michael 2011-03-30 18:15:18

0

也许我是误解,但听起来你应该将TestResult定义为DataContract,然后像平常一样从服务操作中继续返回该类型。对于有权访问类型(DLL)的二进制表示的应用程序,他们可以引用该DLL并使用该服务,就像您今天所做的那样。

将来使用情况下,这是不可能的(或实际)他们有DataContract的二进制表示,可以公开一个MEX端点(和/或使用serviceMetadata行为),将允许消费者打造他们自己的DataContract副本。这个过程的一个例子就是“添加服务引用” - 这会吸引你的服务的元数据,并建立一个DataContracts的本地副本等等。

是的,我认为这是您的服务只暴露/使用定义的DataContracts或本机类型(如字符串)的最佳做法。