Invoke method by MethodInfo
Asked Answered
H

3

7

I want to invoke methods with a certain attribute. So I'm cycling through all the assemblies and all methods to find the methods with my attribute. Works fine, but how do I invoke a certain method when I only got it's MethodInfo.

AppDomain app = AppDomain.CurrentDomain;
Assembly[] ass = app.GetAssemblies();
Type[] types;
foreach (Assembly a in ass)
{
    types = a.GetTypes();
    foreach (Type t in types)
    {
        MethodInfo[] methods = t.GetMethods();
        foreach (MethodInfo method in methods)
        {
            // Invoke a certain method
        }
    }
}

The problem is that I don't know the instance of the class that contains that certain method. So I can't invoke it properly because the methods are not static. I also want to avoid creating a new instance of this class if possible.

Hamlett answered 28/5, 2009 at 8:41 Comment(0)
F
5

This strikes me as an issue in terms of the problem definition rather than coding.

Instance methods depend on which instance they're called on - it makes no sense to call an instance method without caring about what it's called on. (As Martin says, an instance method which doesn't care which instance it's being called on should almost always be static. The only immediate exception I can think of for this is virtual methods, where the instance implicitly specifies which implementation to use.)

Work out what it really means in your context for there to be an annotated instance method. Why are you trying to invoke methods anyway? What's the bigger picture? What context do you have? I strongly suspect you'll want some notion of a context - a collection of objects which you can call the instance methods on.

Foozle answered 28/5, 2009 at 8:50 Comment(1)
What I want to do is to mark methods with a custom attribute to let them be invokeable by a commandline. No matter where they are. But I agree with you that it makes no sense to invoke the same methods on serveral instances where the method is not static. So I'll use this in a kind of manager class which contains a collection of these objects to call an invoke on a specific instance per parameters. I think this will do what I want. ThanksHamlett
F
11

Non-static methods are instance specific so you must instantiate the class to invoke the method. If you have the ability to change the code where it is defined and the method doesn't require itself to be part of an instance (it doesn't access or modify any non-static properties or methods inside the class) then best practice would be to make the method static anyway.

Assuming you can't make it static then the code you need is as follows:

    foreach (Type t in types)
    {
            object instance = Activator.CreateInstance(t);

            MethodInfo[] methods = t.GetMethods();
            foreach (MethodInfo method in methods)
            {                    
                method.Invoke(instance, params...);    
            }
    }
Flutterboard answered 28/5, 2009 at 8:43 Comment(1)
actually; Non-static methods are instance specific. static methods are class specific.Dumpish
F
5

This strikes me as an issue in terms of the problem definition rather than coding.

Instance methods depend on which instance they're called on - it makes no sense to call an instance method without caring about what it's called on. (As Martin says, an instance method which doesn't care which instance it's being called on should almost always be static. The only immediate exception I can think of for this is virtual methods, where the instance implicitly specifies which implementation to use.)

Work out what it really means in your context for there to be an annotated instance method. Why are you trying to invoke methods anyway? What's the bigger picture? What context do you have? I strongly suspect you'll want some notion of a context - a collection of objects which you can call the instance methods on.

Foozle answered 28/5, 2009 at 8:50 Comment(1)
What I want to do is to mark methods with a custom attribute to let them be invokeable by a commandline. No matter where they are. But I agree with you that it makes no sense to invoke the same methods on serveral instances where the method is not static. So I'll use this in a kind of manager class which contains a collection of these objects to call an invoke on a specific instance per parameters. I think this will do what I want. ThanksHamlett
M
0

Actually, I think what you need to do is to create a list of the existing objects and then search the list. So as you create these invokable objects, you would store them into the list (or perhaps the list should be a list of objects of some other kind that also has a description of the invokable object). Then you can scan the list at runtime, find the one that matches the type of event you are handling, and then look up its methodInfo and call .Invoke on the method info, assuming thats what you want to do. You would also need to pass in the appropriate arguments, but you can do that by creating a vector of objects of the right types.

Mechanic answered 17/3, 2012 at 12:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.