【问题标题】:"using" of two different libraries with almost identical functions“使用”两个具有几乎相同功能的不同库
【发布时间】:2013-05-06 07:16:23
【问题描述】:

我正在使用 SOAP Web 服务。 Web 服务为其每个客户指定一个单独的服务 URL。我不知道他们为什么这样做。它们的所有功能和参数在技术上都是相同的。但是,如果我想为每家公司的服务编写一个程序,我必须知道它是有意的。这意味着对于一家名为“apple”的公司,我必须使用以下 using 语句:

using DMDelivery.apple;

另外一个叫“橙子”

using DMDelivery.orange;

但我希望我的程序适用于所有人,并将公司名称或服务参考点作为参数。

更新:如果我必须为每个客户编写一个单独的应用程序,那么我必须让所有客户在每次小的更改时都相互更新,这将是一项低效的工作随着客户数量的增加。

谁能想到解决办法?我将不胜感激。

【问题讨论】:

  • 我猜您目前正在使用“添加服务引用”添加 Web 服务引用,对吗?
  • 我认为您可能想要使用适配器模式或其他一些设计模式(也想到外观)。
  • 每个命名空间里面有什么?型号+合同?事件如果 DMDelivery.apple.MyFunction 和 DMDelivery.orange.MyFunction 看起来是同一个方法,实际上并不相同。这有点复杂。
  • 看看动态Web服务消费/调用/调用。这个codeproject article 可能会派上用场。
  • @RanhiruCooray 是的,我正在使用“添加服务参考”。

标签: c# .net web-services soap


【解决方案1】:

如果您的所有服务都有一个基本合同(接口),您可以使用一种factory 来实例化您的具体服务,并且只在您的客户端代码(调用代码)中引用您的接口。

//service interface
public interface IFruitService{
  void SomeOperation();
}

//apple service
public class AppleService : IFruitService{
  public void SomeOperation(){
    //implementation
  }
}

例如有一种工厂类(你可以把你的using 声明放在这里)

public static class ServiceFactory{
  public static IFruitService CreateService(string kind){
    if(kind == "apple")
      return new AppleService();
    else if(kind == "orange")
      return new OrangeService();
    else
      return null;
  }
}

在您的调用代码中(您只需为包含您的接口的命名空间添加一个using 语句):

string fruitKind = //get it from configuration
IFruitService service = ServiceFactory.CreateService( fruitKind );
service.SomeOperation();

您也可以使用Dependency Injection 原则。

【讨论】:

  • 这是否意味着我应该为每个客户(Apple 一个,Orange 一个)单独实现服务,而它们的几乎所有功能都相同?这将使我的代码大小增加一倍。
  • 不,我试图展示的是每个服务都有自己的实现,正如你所说的“几乎所有的功能都是相同的”,那么你可以创建一个接口(或基类) “隐藏”调用代码的实现。在这种情况下,您的调用代码不知道它是在使用“apple”还是“orange”服务,它只知道它正在使用IFruitService 接口(或commun 基类)的实现。这样,您只需为您的客户端(调用代码)编写一次代码。
  • 这听起来很合理。并且要调用的服务实例(无论是苹果还是橙色)将是一个输入参数,对吗?
  • 对。然后由您(并且取决于您的系统)决定如何检索要使用的“种类”服务:通过配置、方法或类的参数...
【解决方案2】:

如果一切都一样,只是端点地址不同,也许你可以在调用 Web 服务方法之前尝试只更改它。

MyWebServiceObject ws= new MyWebServiceObject();
ws.Endpoint.Address = new System.ServiceModel.EndpointAddress("http://www.blah.com/apple.asmx");

【讨论】:

  • 我的程序中有很多课程。我应该如何处理所有这些“使用”语句?有没有办法全局宣布适用于所有这些类的 using 语句?就像 VB.Net 中的“添加用户导入”。
【解决方案3】:
  1. 在您的实施中使用任何一个客户端。前任。苹果
  2. 编写消息检查器并将其附加到输出点
  3. 在消息检查器中,将类型的名称空间替换为适当的客户端名称空间。 前任: 消息检查器之前:MyClinet.Apple.Type
    消息检查器后:MyClient.Orange.Type,如果 Provider 是 Orange。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-13
    • 2022-11-03
    • 1970-01-01
    相关资源
    最近更新 更多