views:

497

answers:

5

Here is what i want to do, and i know it is possible with perl, php, python and java, but i am working with c#

how can i do the following:

public void amethod(string functionName)
{
    AVeryLargeWebServiceWithLotsOfMethodsToCall.getFunctionName();
}

I want to pass the functionName to the method and I want it to be executed as above.

How this can be done?

Do i need ANTLR or any other tool for this?

Thanks.

+4  A: 

Are you saying that AVeryLargeWebServiceWithLotsOfMethodsToCall is an instance of an object on which you want to invoke a method named functionName? If so:

MethodInfo method = AVeryLargeWebServiceWithLotsOfMethodsToCall.GetType().GetMethod(functionName);
method.Invoke(AVeryLargerWebServiceWithLotsOfMethodsToCall, null);

Or is AVeryLargeWebServiceWithLotsOfMethodsToCall a type on which you want to invoke a static method named functionName? If so:

MethodInfo method = typeof(AVeryLargeWebServiceWithLotsOfMethodsToCall).GetMethod(functionName);
method.Invoke(null, null);
Jason
+2  A: 

It can be done using reflection. However, I believe you need an object reference to go with it.

Example from here

Type t = this.GetType();
MethodInfo method = t.GetMethod("showMessage");
method.Invoke(this, null);

Alternatively, you could use an Action or some other delegate to pass a reference to the function you want to call.

public void amethod(Action function)
{
    function();
}
Jeremy Roberts
+3  A: 

Executing a string as if it were code is possible in c#, but it's not pretty or simple. It's also considered poor practice and insecure (you probably should avoid it in dynamic languages, too).

Instead, do something like this:

public void amethod(Action actionParam)
{
    actionParam();
}

Now, in your case you want to call a web service. Since that ultimately comes down to xml anyway you have a couple options:

  • Bypass the built-in system for calling web services and create your own web request with the correct name in the correct place in the xml.
  • Create delegates for each of the methods in the service to pass around, possibly via reflection.
Joel Coehoorn
"Poor practice and insecure" Can you explain why? There are several frameworks that uses this paradigm, to actually make things dynamic.If it s poor practice and insecure, what would be a better practice and secure?
It's a bad idea to ever execute arbitrary code submitted by users. If it's _your_ string, and you're _sure_ it's your string, that's one thing. But better be **dead** sure of that. You're talking about a whole new category of security hole here, akin to sql injection. Just because a lot of dynamic programs do it anyway doesn't make it right.
Joel Coehoorn
Understood. Yes, I m dead sure :) noone can access it, just for internal use.Thanks.
+5  A: 

You can execute a method by name via Reflection. You need to know the type, as well as the method name (which can be the current object's type, or a method on a different object, or a static type). It looks like you want something like:

public void amethod(string functionName) 
{
    Type type = typeof(AVeryLargeWebServiceWithLotsOfMethodsToCall);
    MethodInfo method = type.GetMethod(functionName, BindingFlags.Public | BindingFlags.Static);
    method.Invoke(null,null); // Static methods, with no parameters
}


Edit in response to comment:

It sounds like you actually want to get a result back from this method. If that's the case, given that it's still a static method on the service (which is my guess, given what you wrote), you can do this. MethodInfo.Invoke will return the method's return value as an Object directly, so, if, for example, you were returning a string, you could do:

public string amethod(string functionName) 
{
    Type type = typeof(AVeryLargeWebServiceWithLotsOfMethodsToCall);
    MethodInfo method = type.GetMethod(functionName, BindingFlags.Public | BindingFlags.Static);
    object result = method.Invoke(null,null); // Static methods, with no parameters
    if (result == null)
        return string.Empty;
    return result.ToString();
    // Could also be return (int)result;, if it was an integer (boxed to an object), etc.
}
Reed Copsey
how do i get back the result ?
I'll edit to show you.
Reed Copsey
+1  A: 

Why don't you just use .NET Remoting? It is made for exactly that.

A completely other solution would be to use the CSharpCodeCompiler class.

codymanix