ソースコードを編集せずに、コードを外部メソッドに挿入したいと考えています。C# メソッドの内容を動的に置換するため、現在のメソッドを自分のメソッドを参照するように置き換えることができます .
実行時に外部メソッド本体を変更できる必要があります。これは、メソッド呼び出しの前とメソッド呼び出しの後にコードを挿入できることを意味します。
変更したいこのメソッドを手動で呼び出すことはできません。 自ら運営するサービスです。
私が試してみました:
- Reflection.Emit -> しかし、これは参照されていない新しいメソッドを作成します。
- Marshall ->
Marshal.GetFunctionPointerForDelegate
、次にメソッドを置換してから、マーシャリングされた関数を呼び出します -> 置換はポインターであり、marhal はポインターを変更するため、機能しません。
状況:
class Program
{
static void Main(string[] args)
{
var oldMethod = typeof(InstanceClassA).GetMethod("OldMethod", BindingFlags.Instance | BindingFlags.Public);
var beforeMethod = typeof(InstanceClassA).GetMethod("BeforeMethod", BindingFlags.Instance | BindingFlags.Public);
oldMethod.Before(() => Console.WriteLine("Called Before"));
oldMethod.Before(() => beforeMethod);
//This is *TESTING* only as I can't manually call the method i want to inject.
var instance = new InstanceClassA();
//Should now call the beforeMethod and the called before
instance.OldMethod("With Before");
//Should call the after method
Console.ReadLine();
}
}
public static class MethodInfoUtils
{
//Will *NOT* allow return values as this should return oldMethod return value
//Will allow Actions and another MethodInfo
public static void Before(this MethodInfo method)
{
// Code to inject code before calling the external method
}
//Will *NOT* allow return values as this should return oldMethod return value
//Will allow Actions and another MethodInfo
public static void After(this MethodInfo method)
{
// Code to inject code after calling the external method
}
}
public class InstanceClassA
{
public bool OldMethod(string message)
{
Console.WriteLine(message);
return true;
}
//message param is equal to the oldMethod param as it is called before the oldMethod is called
public void BeforeMethod(string message)
{
Console.WriteLine("test");
}
}