【问题标题】:Local Interface to an external SOAP web service (C#)外部 SOAP Web 服务的本地接口 (C#)
【发布时间】:2013-07-17 13:57:50
【问题描述】:

我想在父方法中访问外部类(web服务)的方法(web服务在子类中实例化)

场景是这样的: 我有一个名为 ConvertCurrency 的母班,它接受美元并提供卢比。 例如。 int ConvertCurrency(int 美元);

现在市场上有一个标准供应商,它提供了一种任何人都可以在其服务器上托管并创建 Web 服务的软件。因此,假设它托管在两个地方:www.link-A.com/service.asmx 和 www.link-B.com/service.asmx。

我有一个父类:CurrencyConvertor,它有两个子类:Convertor-A 和 Convertor-B。

Class CurrencyConvertor
{
    protected Object Service;

    public Convert(int dollars)
    {
        Service.ConvertCurrency(dollars);
    }
}

Class Convertor-A : CurrencyConvertor
{
    public Convertor-A()
    {
        Service = link-A.service;
    }
}

Class Convertor-B : CurrencyConvertor
{
    public Convertor-B()
    {
        Service = link-B.service;
    }
}


// based on current response-time of the two servers, we decide 
// that B is faster and hence we make the decision at run-time that we should use 
// B's service

CurrencyConvertor cc = new Convertor-B();
cc.Convert(5);

但这不会编译,因为父类不知道所有方法 Service 有什么,它给出了以下错误:

“object”不包含“GetSources”的定义,并且找不到接受“object”类型的第一个参数的扩展方法“GetSources”(您是否缺少 using 指令或程序集引用?)

我想知道有什么办法可以解决这个问题。当然,不必求助于为两个提供者中的每一个创建单独的转换函数。

如果我能以某种方式让“服务”对象知道它的接口(即函数签名),它就会正常工作。

有没有办法解决这个问题?

【问题讨论】:

  • 转换器 a 和 b 是否继承自 CurrencyConverter?
  • 是的@Stephan。感谢您指出这一点 :) 已更新代码以反映相同。

标签: c# web-services oop design-patterns interface


【解决方案1】:

在 CurrencyConvertor 中创建一个名为 GetService() 的抽象方法; 派生类必须以返回服务的方式实现此方法...

在 CurrencyConverter 中:

 public abstract IMyNewServiceThingy GetService();

基类现在可以使用这个类来获取服务并调用它的方法

在每个派生类中:

public override IMyNewServiceThingy GetService()
{
   return Service;
}

在类上设置 Service 变量 - 级别是一个糟糕的决定,更糟糕的是,当您在创建派生类时(在构造函数中)重置它时 - 您永远无法知道当前设置了哪个 Service ..(尤其是在使用IOC 或异步调用)

【讨论】:

  • 我在这里遇到的问题是两个服务的类型不同。 A 是 link-A.service,B 是 link-B.service(link-A 和 link-B 指的是我们在添加两个 Web 引用时得到的两个命名空间)。现在,在基类中,我必须将其设置为: public abstract Object GetServices();在我的程序中,我这样做: Object service = cc.GetService();现在,当我调用任何方法服务时,我会得到同样的错误 - “对象”不包含“GetSources”的定义我是 OOP 的新手,所以如果我误解了你的解决方案,请告诉我。
  • 当服务上调用的方法对两种服务(两种类型)具有相同的签名时,然后为这两种方法创建一个通用接口并返回它.. 嗯,你可能在自动生成时遇到一些问题代码.. - 不知道
  • 对不起..我忘记了返回类型..对象并没有让你走得很远(除非你想在基类中转换对象或使用反射来调用方法 - 但这不是必需的我认为)
  • 谢谢斯蒂芬。我创建了界面并添加了 Web 服务的一种方法。在子类中,当我尝试通过将服务强制转换为接口来返回服务时,它失败了。 public override IWebService GetService() { return (IWebService)link-A.service; } 接口 IWebService { int ConvertCurrency(int Dollar); // 需要添加 web 服务的其余方法 } 这里显式转换失败。我想我会通过添加 Web 服务中存在的所有方法来完成接口,并查看转换是否通过。
  • “尝试通过将服务强制转换为接口来返回服务”将不需要强制转换..当您的类(服务客户端类)实现接口时,您可以将对象返回为-is(您返回一个 IMyNewServiceThingy - 您是否忘记将接口添加到客户端类?)
【解决方案2】:

我终于用反射解决了这个问题(由 Manas Agarwal 提供)

Class CurrencyConvertor cc;
cc = new Convertor-A();

BindingFlags flags = (BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);
MethodInfo m = cc.type.GetMethod(MethodName, flags);
response = (string)m.Invoke(cc.Service, Parameters);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-07
    • 2010-11-03
    • 1970-01-01
    • 1970-01-01
    • 2019-12-25
    相关资源
    最近更新 更多