在运行时附加所有现有事件处理程序的包装器

时间:2012-11-14 23:34:15

标签: c# winforms event-handling

我目前非常需要为现有应用程序进行日志记录,并且无法将我期望的日志记录级别直接添加到代码中。作为一种解决方法,我很乐意在每次触发事件时都完成一定量的日志记录。

我正在考虑一个解决方案,我可以在运行时解析整个应用程序,将所有事件到处理程序绑定包装到事件到包装器到处理程序;理想情况下,也可以在运行时解包它们。在伪代码中,这将是:

IDictionary<Event, Action<object, EventArgs>) originalBindings = ...;

public void SetWrapBindings()
{
   var allBindingsToReplace = Assembly.GetAssembly().GETALLEVENTS()
      .Where(eventInfo => eventInfo.GetOtherMethods().Any());

   foreach(var binding in allBindingsToReplace)
   {
     binding.event -= binding.handler;
     binding.event += HandlerWrapper;
     originalBindings.Add(binding.event, binding.handler);
   }

}

public static void HandlerWrapper(object o, EventArgs e)
{
    // Do some logging
    try
    {
       var handler = originalBindings.TryGetValue(/* something */);
       handler.Invoke(o, e);
    }
    // Do more logging
}

在这堆伪代码中有很多我无法编写的步骤,可能是因为我没有找到正确的API使用,但也许因为某些操作在理论上是不可能的(在这种情况下我我很想知道为什么。这些是:

  • 迭代应用程序的所有事件(这可能很容易)
  • 为我的IDictionary识别一个好的密钥
  • 在每一步中,从上下文中获取相关信息

当然,将一个额外的处理程序绑定到每个现有事件(在没有真正包装处理程序之前/之后执行例程)会有所帮助,但是在try-catch中执行真正的处理程序是一个很大的好处。

仍然非常感谢任何部分答案

1 个答案:

答案 0 :(得分:1)

如果您正在寻找非侵入式系统范围的日志记录,那么最好使用面向方面的编程框架,例如PostSharpThis page为你正在寻找的东西提供了一个不错的起点。

编辑:要添加到此内容,请查看实现EventInterceptionAspect,如果您确实想知道何时引发任何事件。同样,PostSharp博客是一个很好的信息来源,this article显示了这方面的一个实现,它执行添加,删除和调用的简单stdout日志记录。