internal static void PrepareEventTracing()
{
LoadTracingSettings();
// create a dynamic type to hold our handler methods
AppDomain myDomain = AppDomain.CurrentDomain;
var asmName = new AssemblyName( "fCraftEventTracing" );
AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly( asmName, AssemblyBuilderAccess.RunAndSave );
ModuleBuilder myModule = myAsmBuilder.DefineDynamicModule( "DynamicHandlersModule" );
TypeBuilder typeBuilder = myModule.DefineType( "EventHandlersContainer", TypeAttributes.Public );
int eventIndex = 0;
Assembly asm = Assembly.GetExecutingAssembly();
List<EventInfo> eventList = new List<EventInfo>();
// find all events in current assembly, and create a handler for each one
foreach( Type type in asm.GetTypes() ) {
foreach( EventInfo eventInfo in type.GetEvents() ) {
// Skip non-static events
if( (eventInfo.GetAddMethod().Attributes & MethodAttributes.Static) != MethodAttributes.Static ) {
continue;
}
if( eventInfo.EventHandlerType.FullName.StartsWith( typeof( EventHandler<> ).FullName ) ||
eventInfo.EventHandlerType.FullName.StartsWith( typeof( EventHandler ).FullName ) ) {
if( useEventWhitelist && !eventWhitelist.Contains( type.Name + "." + eventInfo.Name, StringComparer.OrdinalIgnoreCase ) ||
useEventBlacklist && eventBlacklist.Contains( type.Name + "." + eventInfo.Name, StringComparer.OrdinalIgnoreCase ) ) continue;
MethodInfo method = eventInfo.EventHandlerType.GetMethod( "Invoke" );
var parameterTypes = method.GetParameters().Select( info => info.ParameterType ).ToArray();
AddEventHook( typeBuilder, parameterTypes, method.ReturnType, eventIndex );
eventList.Add( eventInfo );
eventsMap.Add( eventIndex, eventInfo );
eventIndex++;
}
}
}
// hook up the handlers
Type handlerType = typeBuilder.CreateType();
for( int i = 0; i < eventList.Count; i++ ) {
MethodInfo notifier = handlerType.GetMethod( "EventHook" + i );
var handlerDelegate = Delegate.CreateDelegate( eventList[i].EventHandlerType, notifier );
try {
eventList[i].AddEventHandler( null, handlerDelegate );
} catch( TargetException ) {
// There's no way to tell if an event is static until you
// try adding a handler with target=null.
// If it wasn't static, TargetException is thrown
}
}
}