Web服务代理类实现接口

7

我正在寻找一种方法,使得Web Reference(不是WCF)生成的代理类能够实现一个公共接口,以便在客户端应用程序中轻松地在Web服务访问和“直接”访问我们的业务层之间切换,就像:

public IBusiness GetBusinessObject()
{
  if (_mode = "remote")
    return new BusinessWebService.Business(); // access through web service proxy class
  else
    return new Business(); // direct access
}

然而,自定义类型(例如下面示例中的CustomSerializableType)在生成的代理类中没有被引用。相反,会生成新的、完全相同的类型,这使得代理类无法实现接口。

是否有办法让生成的代理类引用这些类型,或者我做错了什么?我应该考虑将 Web 服务转换为 WCF 服务吗?


详细信息

我们的解决方案由以下四个项目组成:

  • 业务库(包含业务逻辑,访问数据存储)
  • 公共库(包含公共功能,包括CustomSerializableType
  • Web 服务(充当远程客户端和业务层之间的代理)
  • Windows 应用程序

我们的客户希望 Windows 应用程序能够以两种不同的模式运行:

  • 本地模式,在此模式下,应用程序直接使用业务库访问数据
  • 远程模式,在此模式下,应用程序通过与 Web 服务通信来访问数据

为了实现这一点,我们创建了一个接口 IBusiness,它位于公共库中,并包含所有业务方法。

接口

public interface IBusiness
{
  CustomSerializableType DoSomeWork();
}

业务层

public class Business : IBusiness
{
  public CustomSerializableType DoSomeWork()
  {
    // access data store
  }
}

Web服务

public class WebServiceBusiness : IBusiness
{
  private Business _business = new Business();

  [WebMethod]
  public CustomSerializableType DoSomeWork()
  {
    return _business.DoSomeWork();
  }
}

生成的代理类(为了可读性省略了大量代码)

public partial class Business
  : System.Web.Services.Protocols.SoapHttpClientProtocol
{

  public CustomSerializableType DoSomeWork()
  {
    // ...
  }

  public partial class CustomSerializableType {
    // PROBLEM: this new type is referenced, instead of the
    // type in the common library
  }
}

你是否正在使用svcutil.exe生成代理类? - Mike Atlas
不,目前我只是使用Visual Studio 2010内置工具。我尝试过用wsdl.exe玩弄一下,但它并没有解决我的问题。svcutil.exe是更好的选择吗?那不是需要我升级到WCF服务,而不是“遗留”的Web服务吗? - bernhof
1个回答

6
假设您的客户端的默认命名空间为“Client”,并且您的 Web 引用名称为“Proxy”,则执行以下操作:
  1. 在客户端项目的根目录下,创建一个名为“Proxy”的文件夹。
  2. 在该文件夹中,创建一个名为“Business”的类。
  3. 将该类设置为 public 和 partial,并实现您的 IBusiness 接口。
这样,您就不需要修改 Reference.cs 文件。您应该永远不要修改 Reference.cs 或任何其他通过代码生成产生的文件。
请注意,这违反了 SOA 的原则,因为它紧密地将客户端与服务绑定在一起。至少,您应该在单独的项目中定义那些接口,以便您只在客户端和服务之间共享“interface”项目。

好的,谢谢。我非常感激你的帮助 :) 我在哪里可以阅读有关WCF解决此问题的信息? - bernhof
虽然这个答案在字面上是“正确”的,但它并没有真正回答问题。难点在于重新实现完全相同的代理类型——一个“真正”的答案应该描述如何自动化这个过程。但根据以上评论,似乎不可能做到这一点,所以除了一开始就在WCF中完成它之外,可能没有其他“真正”的答案。 - drzaus
@drzaus:如果你坚持使用传统技术,那么你可以使用T4模板自动创建部分类。 - John Saunders
@JohnSaunders:哈哈,这不是我的坚持!但我真正想说/问的是,难道没有办法自动生成服务代理并_重用_现有的模型类,而不是Web服务引用工具重新创建新的代理模型,这些模型实际上是相同的吗?我假设答案是否定的。 - drzaus
@drzaus:使用传统的 ASMX 技术无法完成此操作。但使用 WCF 则非常简单。 - John Saunders
显示剩余4条评论

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