You cannot do this out of the box. You need to write your own execution code that uses reflection to figure out what and how to execute. Below, I will share a simple example.
First, you need the attributes to describe the type of methods.
class InitMethodAttribute : Attribute
{
public InitMethodAttribute():base()
{ }
};
class CleanupMethodAttribute : Attribute
{
public CleanupMethodAttribute() : base()
{ }
};
class RunMethodAttribute : Attribute
{
public RunMethodAttribute() : base()
{ }
};
We'll use this on an example class. Notice that all the methods in this example are private. They can be invoked through reflection. Also, notice that for simplicity they do not have parameters and don't return anything. You can work around this example and change it to support parameters too.
class Example
{
[InitMethod]
private void Init()
{
Console.WriteLine("Initializing...");
}
[InitMethod]
private void InitMore()
{
Console.WriteLine("More initializing...");
}
[RunMethod]
private void Run()
{
Console.WriteLine("Running...");
}
[CleanupMethod]
private void Cleanup()
{
Console.WriteLine("Cleaning up...");
}
}
The next class, called executor, takes an object and looks at its type, identifying methods and looking at their attributes. Eventually, if the RunMethod
attribute is found on any method, the method is executed. Before it are executed all the InitMethod
decorated methods and after it all the CleanupMethod
decorated methods.
static class Executor
{
public static void Run(object obj)
{
var type = obj.GetType();
var methods = type.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
var initMethods = new List<MethodInfo>();
var cleanMethods = new List<MethodInfo>();
foreach (var method in methods)
{
var initattrs = method.GetCustomAttributes(typeof(InitMethodAttribute));
var cleanattrs = method.GetCustomAttributes(typeof(CleanupMethodAttribute));
if (initattrs != null && initattrs.Count() > 0)
initMethods.Add(method);
else if (cleanattrs != null && cleanattrs.Count() > 0)
cleanMethods.Add(method);
}
foreach (var method in methods)
{
var runattrs = method.GetCustomAttributes(typeof(RunMethodAttribute));
if(runattrs != null)
{
var runattr = runattrs.FirstOrDefault();
if(runattr != null)
{
foreach (var m in initMethods)
m.Invoke(obj, null);
method.Invoke(obj, null);
foreach (var m in cleanMethods)
m.Invoke(obj, null);
}
}
}
}
}
The following program uses all this:
class Program
{
static void Main(string[] args)
{
var example = new Example();
Executor.Run(example);
}
}
The output is:
Initializing...
More initializing...
Running...
Cleaning up...