不生成程序集调用WCF服务

8
我正在尝试使用C#编写一些代码,通过导入WSDL、检查它,然后动态地调用WCF服务。
我调用的服务可能会不时更改 - 因此,如果确实更改了,我希望我的客户端能够了解到新方法以及对调用的新输入参数和输出参数,而无需重建客户端。
其中一个可能的解决方案是动态导入和编译服务引用。在此处概述:Creating an assembly on the fly from a WSDL 如果可能的话,我想避免生成程序集并反射它。
我查看了链接中动态代理的代码,并使用框架类来进行导入。该类是WsdlImporter。所以我认为很好 - 我可以使用它并检查WSDL模式,确定存在哪些调用以及可用的输入和输出。
问题在于WsdlImporter创建的MessagePartDescription对象中缺少类型信息。显然,这是因为它尚未找到类型 - 请参见Brian的问题回答中的响应。
那么我应该如何继续?我完全走错了吗?

你能给出一个现实世界的例子说明这会有什么用处吗?你的客户端是否向用户呈现了UI,让他们选择要调用的方法,也许是某种调度程序之类的东西?此外,动态创建程序集有什么问题吗?那听起来相当简单。您是否预见到比反射更简单的东西?我很难想象那会是什么。 - JohnOpincar
1
这将用于调用WF服务。工作流程可能会发生变化 - 可以添加/删除步骤等。 - Neil
1
准确解析WSDL并不容易。我更倾向于使用平台内置的工具来完成这个任务(使用反射进行动态组装),而不是自己实现。除非我误解了你的概念,否则动态组装生成将是你最不稳定的问题之一。 - JohnOpincar
1
@John - 我同意,我不想涉足WSDL解析的业务。.NET框架内置了一个WSDL解析器:WsdlImporter- 但它并不公开有关操作参数类型的信息。不知何故,其他框架部分可以从WSDL导入器中获取这些信息 - 但像我这样的凡人却不能。 - Neil
1
@Neil:.NET 的许多部分都可以动态生成代码,包括 ASP.NET。这并不涉及任何特定的安全问题。你信任 WSDL 的来源吗?如果是,那么 WSDL 就不会给你带来任何安全问题。 - John Saunders
显示剩余4条评论
2个回答

5

这可能不是一个答案,但我会将其发布为一个答案,以充分描述我的观点。

动态代理:
在我看来,这是技术使用的错误示例。这是WSDL的基本行为——如果它发生了改变,你必须更改客户端,或者你必须进行良好的WSDL版本控制并创建新的客户端。

你仍然必须以某种方式告诉你的客户端获取WSDL——这是否意味着你将在每次调用之前解析WSDL?这似乎不是一个好主意。

类型信息确实不是WSDL的一部分,因为默认情况下,WSDL是生成为互操作性的。CLR类型对于互操作性并不是必需的操作。当你通过添加服务引用或Svcutil创建服务代理时,它将生成代码来定义WSDL中定义的类型。然后需要编译该代码。

你可以尝试使用NetDataContractSerializer而不是默认的DataContractSerializer。NetDataContractSerializer将CLR类型信息添加到WSDL中,但我仍然期望新类型必须为您的客户端所知道——这意味着使用具有类型的新程序集并由客户端使用。这几乎听起来像是同样的方法,只是使用新的静态客户端代理部署程序集。

动态WF客户端
我也不认为这种架构有太多用途——你仍然需要更改客户端以反映新的WF步骤,不是吗?

改变WF
我们在谈论Windows Workflow Foundation吗?我几乎无法想象这样的情景:你创建一个WF,将其公开为服务,然后再次更改它。当你将WF作为服务公开时,你可能正在定义长时间运行的WF。长时间运行的WF使用基于序列化的持久性(至少在WF 3.5中是这样,但我相信在WF 4中也是如此)。当你更改WF定义时,所有已持久化的WF都很可能注定要失败,因为它们永远不会反序列化。这种情况通常通过并行部署新旧版本来解决,其中旧版本仅用于完成不完整的WF。同样意味着需要新的客户端。


感谢您的评论,正如您所说,它并没有解决我的问题,但我会点赞,因为它引发了思考 - 我同意您对WSDL与类型相关性的评估。然而,如果WsdlImporter能让我看到WSDL类型,我就可以达到想要去的地方。我不需要CLR类型。请参见我的下一个关于动态客户端的评论。 - Neil
1
我们正在谈论长时间运行的WF类。没有理由为了添加一个步骤到我的工作流程而需要重建不执行该步骤的客户端。此外,如果您想构建一个支撑系统来管理客户与工作流的交互,并使所有客户都符合标准接口,那么您需要通过比WF服务创建的API更窄的API来汇集所有调用。 - Neil
@Neil:在这种情况下,我可能会选择不同的方向。我会将所有这些复杂性保留在服务器端。这意味着在您的进程中托管WF,并公开具有为WF更改准备的众所周知接口的Web服务。这是一个高层次的想法,但应该是可行的,而且比“动态Web服务客户端”更容易。 - Ladislav Mrnka

1

+1 感谢你的回答 - 它可能对其他人也有用。不幸的是,我们对 WF 生成的 WCF 服务的控制有限,所以我们无法采用那种方法。 - Neil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接