C # Внедрить код во внешний метод во время выполнения, используя AOP - PullRequest
1 голос
/ 17 июня 2019

Я хочу внедрить код во внешний метод, без редактирования исходного кода.Я уже могу заменить текущий метод ссылкой на свой собственный метод, потому что Динамически заменять содержимое метода C #? .

Мне все еще нужно изменить тело внешнего метода ввремя выполнения, что означает возможность внедрения кода перед вызовом метода и после вызова метода.

I не может вручную вызвать этот метод, который я хочу изменить,это служба, которая работает сама по себе.

Я пробовал:

  1. Reflection.Emit -> но это создает новый метод, на который нет ссылок.
  2. Marshall -> Marshal.GetFunctionPointerForDelegate, а затем заменить метод, чтобы после этого вызывать маршаллированную функцию -> не работает, поскольку замена является указателем, а маршал меняет указатель.

Ситуация:

    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");
        }
    }
...