0

考虑以下 Visual Studio 项目结构

  • 项目A.csproj
    • 类.cs
  • 项目B.csproj
    • 参考
      • 项目A
    • 网络参考
      • 网络服务
  • AWebService.csproj
    • 参考
      • 项目A
    • ReturnAClassViaWebService.asmx

当 ProjectB 将 Web 引用添加到 AWebService 并自动生成用于访问 AWebService 的所有代理代码(包括 AClass 的新实现)时,就会出现此问题。由于我们所有其他代码都需要使用 ProjectA 中定义的 AClass,因此我们被迫将从服务返回的 AWebService.AClass 转换为我们可以使用的东西。

我们目前正在考虑两种解决方案,但都不是理想的。

  • 手动编辑生成的 Reference.cs 以删除 AClass 的新定义
  • 将 AWebService.AClass 序列化为流,然后反序列化为 ProjectA.AClass

有没有人有更好的解决方案?对于其他开发人员来说,这似乎很常见。

理想情况下,我们希望在 ProjectB 中生成代理代码来引用 ProjectA.AClass,而不是生成一个全新的实现。

我们的环境是使用 .NET 2.0 的 VS 2008。

4

3 回答 3

2

我遇到了与您描述的相同的问题,并且我尝试了您指定的两个选项,但对其中任何一个都不完全满意。

我们都有这个问题的原因至少部分是因为共享库在消费者和提供者之间的网络服务解决方案违反了网络服务设计的公认模式和实践。在消费者方面,知道 WSDL发布的接口就足够了。

尽管如此,如果您准备接受 Web 服务提供者和 Web 服务使用者之间的紧密耦合,并且您确定您当前的客户端永远不会被其他客户端(可能无法引用共享库)替换,然后我明白为什么提议的解决方案似乎是构建应用程序的一种巧妙方法。重要提示:我们真的可以诚实地回答这两个问题吗?可能不是。

回顾一下:

  1. 当您在某种共享库(在客户端和服务器上都使用)中定义了类(例如强类型数据集)时,就会出现问题。
  2. 您的一些共享类在您的 Web 服务定义的接口中使用。
  3. 添加 Web 引用时,在 Web 引用命名空间中定义了代理类(为您的共享类)。
  4. 由于命名空间不同,代理类与其在共享库中的实际对应物是不兼容的。

如果您想继续进行共享库设置,可以尝试以下四种解决方案:

  1. 不。在客户端使用代理类。这就是它的目的。除非您同时想要利用 Web 服务 WSDL 未公开的共享库的各个方面,否则它工作得很好。
  2. 实现或使用提供的类的复制/复制功能(例如,您可以尝试将一个强类型数据集 Merge() 到另一个)。演员显然是不可能的,并且复制选项通常也不是一个很好的解决方案,因为它往往会产生不良的副作用。例如,当您将一个数据集合并到另一个数据集中时,目标数据集中的所有行都将被标记为“已更改”。这可以通过 AcceptChanges() 恢复,但是如果接收到的几行实际发生了更改怎么办。
  3. 将所有内容(基本数据类型除外)序列化为字符串(然后再返回到消费者端)。失去类型安全性是这种方法的一个重要弱点。
  4. 删除 Reference.cs 中共享类的显式声明,并从 Reference.cs 中提到的共享类中剥离命名空间。这可能是最好的选择。你得到真正想要的。共享类由 Web 服务返回。此解决方案唯一令人讨厌的缺点是,每当您更新 Web 引用时,您对 reference.cs 文件的修改都会丢失。相信我:这可能会很烦人。

这是一个类似讨论的链接:

于 2011-03-16T22:43:13.357 回答
0

您可以通过单击“添加服务引用”表单上的“高级”按钮在客户端和服务之间重用现有的引用类型。确保选中“在引用的程序集中重用类型”复选框,并且在生成服务客户端时,它应该重用项目 A 中的所有类型。

在过去的版本中,这并不总是正常工作,我必须通过选择“在指定的引用程序集中重用类型”选项,然后在列表框中检查适当的程序集来明确选择共享类型程序集。但是,我刚刚使用 VS 2008 SP1 对此进行了测试,它似乎可以按预期工作。显然,您需要确保服务项目和客户端项目使用的类型都来自项目 A。

希望这会有所帮助。

于 2011-03-11T18:48:17.213 回答
-1

我们的一个项目遇到了类似的问题。因为我们有几个依赖项,所以我们最终创建了一个循环引用,因为项目 1 需要来自项目 2 的对象,但是项目 2 无法在项目 3 之前构建,项目 3 依赖于项目 1 来构建。

为了解决这个问题,我们从两个项目中提取了所有公共独立类,并将它们放在一个库中。最后我们创建了这样的东西:

  • 框架.对象
  • 框架.接口
  • 框架.实现
  • 网络服务

在我们的例子中,WebService 将链接到所有项目,而外部方将仅链接到要使用的对象和接口类。实际的实现是在运行时通过反射耦合的。

希望这可以帮助

于 2011-03-08T08:29:21.050 回答