假设我有以下(相当常见的)模型
客户端调用Web服务请求 - >请求已添加到服务器队列 - >服务器通过Web服务调用第三方应用程序 - >第三方应用程序通知服务器事件处理已完成 - >服务器通知客户端请求已完成
我想知道的是'服务器通过Web服务调用第三方应用'阶段。第三方应用程序公开在应用程序内配置的Web服务方法。例如,我可能会在这个应用程序中创建一个名为'MultiplyByTwo'的方法。然后我点击“GO”,它会生成一个Web服务,其中包含BeginCalculateMultiplyByTwo和EndMultiplyByTwo(使用IAsync模型)等方法。这很棒。
现在我正在创建一个队列对象,以便多个客户端可以请求此服务并让服务器将它们排队以便顺序执行。所以这个队列对象将有一个类似runNext()的方法,它将调用第三方应用程序上的Web服务。只要我知道被调用的方法的名称(在这种情况下是BegingCaculateMultiplyByTwo),这很好,但是如果我想动态更改方法的名称呢?
所以在第三方应用程序中,我更改了我的Web服务方法并称之为'MultiplyByThree'。这将通过可预测的命名方案公开BeginMultiplyByThree和其他一些方法。如何设置我的类以动态调用我还不知道名称的方法?
理想情况下,如果我可以在app.config文件中设置要调用的方法的名称,那将是很好的。
我想这是我可以通过反思实现的东西?
答案 0 :(得分:5)
你当然可以通过反思来做到这一点:
MyClass o = new MyClass();
MethodInfo method = o.GetType().GetMethod("UnknownMethod",
BindingFlags.Instance | BindingFlags.Public);
MyRetValue retValue = (MyRetValue)
method.Invoke(o, new object[] { "Arg1", 2, "Arg3" });
答案 1 :(得分:2)
为了扩展罗伯特的答案,你可以用泛型和东西来做:
public TReturn DynamicInvoker<T, TReturn>(T obj, string methodName, param[] args){
MethodInfo method = obj.GetType.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public);
(TResult)method.Invoke(obj, args);
}
如果你想让它变得非常可怕,你可以将它作为一个静态的对象方法。您也可以将BindingFlags
作为方法参数传递。
答案 2 :(得分:0)
也许this会有所帮助 - 它是一个使用反射的动态Web服务方法执行器。
答案 3 :(得分:0)
只有在您已经知道需要调用所有方法的代理(例如来自wsdl.exe)时,才能使用反射。如果您没有代理服务器,那么您的反思就会失败。例如,如果您的中间层需要能够调用Web服务中尚不知道的方法。
另请注意,如果Web服务方法采用非基元,则反射也将更难。
WSDL - Web服务描述语言。
这意味着Web服务是自我描述的。所有WSDL.exe正在创建和编译代理类和方法,因此您不必直接使用xml。
并非您想要自己动手,但Web服务本质上只是一种将xml用于请求和结果的RPC机制。因此,您不需要使用花哨的代理对象,只需将xml发送到Web服务并接收xml响应并对其进行解释。