views:

575

answers:

5

Suppose I have the following (rather common) model

Client invokes web service request -> request added to server queue -> server invokes 3rd party app via web service -> 3rd party app notifies server that event processing is finished -> server notifies client that request is completed

What I am wondering about is the 'server invokes 3rd party app via web service' stage. The 3rd party app exposes web service methods that are configured inside the application. For instance, I might create a method in this app called 'MultiplyByTwo'. Then I click 'GO' and it generates a web service with methods like BeginCalculateMultiplyByTwo and EndMultiplyByTwo (using the IAsync model). This is great.

Now I am creating a queue object so that multiple clients can request this service and have the server queue them up for sequential execution. So this queue object will have a method like runNext() that will invoke the web service on the 3rd party app. This is great so long as I know the name of the methods that are being called (BegingCaculateMultiplyByTwo in this case), but what if I want to dynamically change the name of the method?

So in the 3rd party app, I change my web service method and call it 'MultiplyByThree'. This will expose BeginMultiplyByThree and some other methods with a predictable naming scheme. How can I set my class up to dynamically call a method of which I dont yet know the name?

Ideally if I could set the name of the method to be called in an app.config file that would be great.

I suppose this is something I can achieve via reflection?

A: 

Maybe this will help - it's a dynamic web service method executor using reflection.

Lee Harold
+5  A: 

You can certainly do this via reflection:

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" });
Robert Wagner
+2  A: 

To expand on Robert's answer you can do it with generics and stuff:

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);
}

If you wanted to make it completely horrible you can do that as a static method of object. You also can pass the BindingFlags as a method parameter.

Slace
A: 

Reflection will only work if you already have a proxy (e.g. from wsdl.exe) that already knows all of the methods that need to be called. If you don't have the proxy, you're out of luck with reflection. For example if your middle layer needs to be able to call methods in the web service that it doesn't yet know about.

Note also reflection will also be harder to do if the web service methods take non-primitives.

WSDL - Web Service Description Language.

What it means is that Web Services are self-describing. All WSDL.exe is doing is creating and compiling proxy classes and methods so you don't have to work with the xml directly.

Not that you want to roll-your-own, but Web Services are essentially just an RPC mechanism that use xml for requests and results. So you don't need to use the fancy proxy objects, you just need to send xml to the web service and receive an xml response and interpret it.

Robert Paulson
A: 

Robert: I can get access to the wdsl file (and generate a proxy class dynamically), but do I really need it? All that will change is the service name and the base name for the method.

Alex
I'd say so as there is a lot of scaffolding in the proxy class.
Robert Wagner