To call a method, you need to instantiate a class. To instantiate a class, you need to know the type.
So we need to
- find all classes, that contain methods marked with the
Invoke attribute
- Then instantiate those classes
- Call all marked methods.
Let's first define the attribute :
public class InvokeAttribute : Attribute
{
}
You can use this attribute to mark the methods:
public class TestClass1
{
[Invoke]
public void Method1()
{
Console.WriteLine("TestClass1->Method1");
}
[Invoke]
public void Method2()
{
Console.WriteLine("TestClass1->Method2"););
}
}
public class TestClass2
{
[Invoke]
public void Method1()
{
Console.WriteLine("TestClass2->Method1");
}
}
Now how to find and call these methods:
var methods = AppDomain.CurrentDomain.GetAssemblies() // Returns all currenlty loaded assemblies
.SelectMany(x => x.GetTypes()) // returns all types defined in this assemblies
.Where(x => x.IsClass) // only yields classes
.SelectMany(x => x.GetMethods()) // returns all methods defined in those classes
.Where(x => x.GetCustomAttributes(typeof(InvokeAttribute), false).FirstOrDefault() != null); // returns only methods that have the InvokeAttribute
foreach (var method in methods) // iterate through all found methods
{
var obj = Activator.CreateInstance(method.DeclaringType); // Instantiate the class
method.Invoke(obj, null); // invoke the method
}
The snippet above will check all loaded assemblies. The linq query
- selects all types and filters all classes
- it then reads all methods defined in those classes
- and checks that those methods are marked with the
InvokeAttribute
This gives us a list of MethodInfos. A method info contains the DeclaringType, which is the class the method was declared in.
We can use Activator.CreateInstance to instantiate an object of this class. This will only work if the class has a public constructor without parameters.
Then we can use the MethodInfo to invoke the method on the previously created class intance. This will only work if the method doesn't have parameters.