调用 WCF 服务而不生成程序集
我正在尝试用 C# 编写一些代码,通过导入 WSDL、检查它然后动态调用它来动态调用 WCF 服务。
我调用的服务可能会不时发生变化 - 因此,如果确实如此,我希望我的客户端了解新方法以及新的输入参数和调用的输出参数,而无需重建我的客户端。
一种可能的解决方案是即时导入和编译服务引用。
此处概述: 创建程序集来自 WSDL 的苍蝇
我想避免生成程序集,然后如果可能的话对其进行反思。
我查看了链接中动态代理的代码,他们使用框架类来进行导入。此类是WsdlImporter
。所以我的想法很好 - 我可以使用它并检查 WSDL 模式并确定存在哪些调用以及哪些输入和输出可用。
问题在于 WsdlImporter
创建的 MessagePartDescription
对象中缺少类型信息。显然这是缺失的因为它不能尚未找到类型 - 请参阅 Brian 对问题的答复。
那么关于我应该如何进行的任何建议?我在这里完全走错路了吗?
I am trying to write some code in C# that will call a WCF service on the fly by importing the WSDL, examining it and then making calls to it dynamically.
The service I am calling can change from time to time - so if it does I want my client to know about new methods and new input parameters and output parameters to the calls, without rebuilding my client.
One possible solution to this is to import and compile a service reference on the fly.
Outlined here: Creating an assembly on the fly from a WSDL
I would like to avoid the generation of an assembly and then reflecting over it if possible.
I looked into the code of the dynamic proxy in the link and they use a framework class to do the import. This class is the WsdlImporter
. So I had thought great - I can use that and examine the WSDL schema and determine what calls are present and what inputs and outputs are available.
The problem is that the type information is missing in the MessagePartDescription
objects that the WsdlImporter
creates. Apparently this is missing because it cannot find the types yet - see the response to the question from Brian.
So any advice on how I should proceed? Am I completely on the wrong track here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这可能不是一个答案,但我会将其作为答案发布以充分描述我的观点。
动态代理:
在我看来,这是错误使用技术的例子。这是 WSDL 的基本行为 - 如果它发生变化,您就必须更改客户端,或者必须进行良好的 WSDL 版本控制并创建新客户端。
您仍然必须以某种方式让您的客户端获取 WSDL - 这是否意味着您将在每次调用之前解析 WSDL?似乎不是一个好主意。
有关类型的信息实际上不是 WSDL 的一部分,因为默认情况下 WSDL 是作为可互操作生成的。 CLR 类型不是互操作性所需的操作。当您通过添加服务引用或 Svcutil 创建服务代理时,它将为 WSDL 中定义的类型生成代码。然后需要编译该代码。
您可以尝试使用
NetDataContractSerializer
而不是默认的DataContractSerializer
。 NetDataContractSerializer 将 CLR 类型信息添加到 WSDL 中,但我仍然希望您的客户端必须了解新类型 - 这意味着使用类型部署新程序集并由客户端使用它。当简单地使用新的静态客户端代理部署程序集时,这听起来几乎是相同的方法。动态WF客户端
我也没有看到这种架构的太多使用 - 您仍然需要更改客户端以反映新的 WF 步骤,不是吗?
更改WF
我们谈论的是 Windows 工作流基础吗?我很难想象创建 WF、将其公开为服务然后更改它的场景。当您将 WF 作为服务公开时,您可能正在定义长时间运行的 WF。长时间运行的 WF 使用基于序列化的持久性(至少在 WF 3.5 中,但我相信在 WF 4 中也是如此)。当您更改 WF 定义时,所有持久的 WF 很可能都会失败,因为它们永远不会反序列化。这种情况通常通过新旧版本并行部署来解决,其中旧版本仅用于完成不完整的WF。这又意味着新客户。
This is probably not an answer but I will post it as one to fully describe my opinion.
Dynamic proxy:
IMO this is example of wrong usage of technology. It is elementary behavior of WSDL - if it changes you have to change client or you have to make good WSDL versioning and create new client.
You still have to somehow say your client to get WSDL - does it mean that you will parse WSDL before each call? Doesn't seem like a good idea.
Information about types is really not part of WSDL because by default WSDL is generated as interoperable. CLR types are not operation needed for interoperability. When you create service proxy by Add service reference or Svcutil it will generate code for types defined in WSDL. That code then need to be compiled.
You can try to use
NetDataContractSerializer
instead of defaultDataContractSerializer
. NetDataContractSerializer adds CLR type information into WSDL but I still expect that new types must be known to your clients - it means deploying new assembly with types and use it by clients. This almost sounds like same approach when simply deploying assembly with new static client proxy.Dynamic WF client
I also don't see too much usage of this architecture - you still need to change client to reflect new WF steps, don't you?
Changing the WF
Are we talking about Windows Workflow foundation? I can hardly imagine scenario where you create WF, expose it as a service and then change it. When you expose WF as service you are probably defining long running WF. Long running WFs use persistance which is based on serialization (at least in WF 3.5 but I believe it is same in WF 4). When you change WF definition, all persisted WFs are most probably doomed because they will never ever deserialize. This situation is usually solved by parallel deployment of new and old version where old version is only used to finish incomplete WFs. Again it means new clients.
如果换个角度看问题。您是否需要每次都重新生成代理,或者您是否需要一个在情况发生变化时继续有效的合约?
WCF 有一个针对此 IExtensibleDataContracts 的机制,请参阅:http: //msdn.microsoft.com/en-us/library/ms731083%28v=VS.100%29.aspx
可以找到合同版本控制的最佳实践此处
If you look at the problem from a different angle. Do you need to regenerate the proxy each time or do you need a contract that continues to work when things change?
WCF has a mechanism for this IExtensibleDataContracts see: http://msdn.microsoft.com/en-us/library/ms731083%28v=VS.100%29.aspx
Best practices for versioning of contracts can be found here