using System; using System.Diagnostics; using System.Collections; using System.Reflection; using System.Reflection.Emit; namespace SpyTools { // the EventSpy will call your delegate whenever an event occurs. public delegate void SpyEventHandler(object sender, SpyEventArgs e); // Event args to report the name of the event. public class SpyEventArgs : EventArgs { private String evName; private EventArgs args; private string partName; public String EventName { get { return evName; } } public EventArgs EventArgs { get { return args; } } public String EventPartName { get { return partName; } } public SpyEventArgs(String s, String part, EventArgs e) { evName = s; args = e; partName = part; } } // Main EventSpy class public class EventSpy : Object { public event SpyEventHandler SpyEvent; public EventSpy(String spyname, Object o, string theEvent) { // create dynamic assembly AssemblyName name = new AssemblyName(); name.Name = "EventSpy" + spyname; AssemblyBuilder asm = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run); // create dynamic module ModuleBuilder mod = asm.DefineDynamicModule("EventSpyModule", true); // public class EvSpyImpl // { // private EventSpy spy; // public EvSpyImpl(EventSpy s) // { // spy = s; // } // public void OnEventXxx(object o, EventXxxArgs e) // { // spy.ReportEvent("EventXxx", o, e); // } // } // TypeBuilder helperClass = mod.DefineType("EvSpyImpl", TypeAttributes.Public); FieldBuilder fld = helperClass.DefineField("spy", typeof(EventSpy), FieldAttributes.Private); // ldarg.0 // call instance void [mscorlib]System.Object::.ctor() // ldarg.0 // ldarg.1 // stfld class SpyTools.EventSpy SpyTools.EventSpy::spy // ret // ConstructorBuilder ctor = helperClass.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, new Type[] { typeof(EventSpy) }); ILGenerator ilctor = ctor.GetILGenerator(); ilctor.Emit(OpCodes.Ldarg_0); ConstructorInfo basector = typeof(Object).GetConstructor(new Type[0]); ilctor.Emit(OpCodes.Call, basector); ilctor.Emit(OpCodes.Ldarg_0); ilctor.Emit(OpCodes.Ldarg_1); //ilctor.Emit(OpCodes.Ldarg_2); ilctor.Emit(OpCodes.Stfld, fld); ilctor.Emit(OpCodes.Ret); // ldarg.0 // ldfld class SpyTools.EventSpy SpyTools.EventSpy::spy // ldstr "EventXxx" // ldarg.1 // ldarg.2 // callvirt instance void SpyTools.EventSpy::ReportEvent(string, // object, class [mscorlib]System.EventArgs) // ret // Type targType = o.GetType(); BindingFlags whichEvents = BindingFlags.Instance | BindingFlags.Public; EventInfo[] allEvents = targType.GetEvents(whichEvents); MethodInfo miReportEvent = this.GetType().GetMethod("ReportEvent"); EventInfo ev = targType.GetEvent(theEvent); { Type delgType = ev.EventHandlerType; MethodInfo invoke = delgType.GetMethod("Invoke"); ParameterInfo[] prams = invoke.GetParameters(); int len = prams.Length; Type[] mthparams = new Type[len]; for (int i = 0; i < len; i++) { mthparams[i] = prams[i].ParameterType; } String mthname = "On" + ev.Name; MethodBuilder mthd = helperClass.DefineMethod( mthname, MethodAttributes.Public, typeof(void), mthparams); ILGenerator il = mthd.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, fld); il.Emit(OpCodes.Ldstr, ev.Name); il.Emit(OpCodes.Ldstr, spyname); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldarg_2); il.Emit(OpCodes.Callvirt, miReportEvent); il.Emit(OpCodes.Ret); } Type mytype = helperClass.CreateType(); Object spyimpl = Activator.CreateInstance(mytype, new Object[] { this }); //foreach (EventInfo ev2 in allEvents) { ev.AddEventHandler(o, Delegate.CreateDelegate(ev.EventHandlerType, spyimpl, "On" + ev.Name)); } } public void ReportEvent(String name, String partName, Object sender, EventArgs e) { SpyEvent(sender, new SpyEventArgs(name, partName, e)); } } }