如何在运行时扩展方法?

时间:2013-12-12 15:00:17

标签: c# .net reflection aop expandoobject

这是班级:

class Foo
{
    private void Boo()
    {
        // Body...
    }

    // Other members...
}

我需要的是:

  • 在运行时创建一个Foo2类,其中包含所有Foo类成员的副本。
  • Foo2类中,按Boo方法替换Boo2方法,其内容在某种程度上交替出现。
  • 创建Foo2的实例并调用Boo2

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

如果不是此类框架的主要目的,您可以在运行时使用.NET AOP Framework事件来执行此操作。

如果您的方法不是虚拟的,我会积极处理一个可以处理它的新事件。

您可以查看NConcern .NET runtime AOP Framework

猴子补丁"方面" :

<td th:if="${trip.tripStatus} == 'ACCEPTED'" th:text="${trip.tripStatus}"></td>

补丁:

public class MonkeyPatch : IAspect
{
    static public void Patch(MethodInfo oldMethod, MethodInfo newMethod)
    {
        //update monkey patch dictionary
        MonkeyPatch.m_Dictionary[oldMethod] = newMethod;

        //release previous monkey patch for target method.
        Aspect.Release<MonkeyPatch>(oldMethod);

        //weave monkey patch for target method.
        Aspect.Weave<MonkeyPatch>(oldMethod);
    }

    static private Dictionary<MethodInfo, MethodInfo> m_Dictionary = new Dictionary<MethodInfo, MethodInfo>();

    public IEnumerable<IAdvice> Advise(MethodInfo method)
    {
        if (MonkeyPatch.m_Dictionary.ContainsKey(_Method))
        {
            yield return Advice(MonkeyPatch.m_Dictionary[_Method]);
        }
    }
}

在第二手牌中,如果您只是需要在原始通话后拨打电话,那么您处于AOP目标,您就可以这样做......

观察方面:

static public void main(string[] args)
{
    //create Boo2, a dynamic method with Boo signature.
    var boo2 = new DynamicMethod("Boo2", typeof(void), new Type[] { typeof(Foo) }, typeof(Foo), true);
    var body = boo2.GetILGenerator();

    //Fill your ILGenerator...
    body.Emit(OpCodes.Ret);

    //Apply the patch
    MonkeyPatch.Patch(typeof(Foo).GetMethod("Boo"), boo2);
}

用例:

public class Observation : IAspect
{
    static public void Observe(MethodInfo method, Action action)
    {
        //update observation dictionary
        Observation.m_Dictionary[method] = action;

        //release observation aspect for target method
        Aspect.Release<Observation>(method);

        //weave observation aspect for target method.
        Aspect.Weave<Observation>(method);
    }

    static private Dictionary<MethodInfo, Action> m_Dictionary = new Dictionary<MethodInfo, Action>;

    public IEnumerable<IAdvice> Advice(MethodInfo method)
    {
        if (Observation.m_Dictionary.ContainsKey(method))
        {
            yield return Advice.Basic.After(Observation.m_Dictionary[method]);
        }
    }
}