Click here to Skip to main content
15,885,915 members
Articles / Programming Languages / C#

Using Reflection to Manage Event Handlers

Rate me:
Please Sign up or sign in to vote.
4.90/5 (7 votes)
26 Oct 2010CPOL4 min read 39.3K   500   23  
How to wire up delegates to events using reflection
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace TestEvent
{
	class Program
	{
		static void Main( string[] args )
		{
			MyClass c = new MyClass();

			EventInfo eInfo = null;
			foreach( EventInfo e in c.GetType().GetEvents() )
			{
				foreach( object o in e.GetCustomAttributes( true ) )
				{
					if( o is PubEventAttribute )
					{
						eInfo = e;
						ParameterInfo[] actionArgs = eInfo.EventHandlerType.GetMethod( "Invoke" ).GetParameters();
						if( actionArgs.Length == 1 )
						{
							// create the ActionPublisher instance that matches our event
							Type publisherType = typeof( ActionPublisher<> ).MakeGenericType( new Type[] { actionArgs[ 0 ].ParameterType } );
							object publisher = Activator.CreateInstance( publisherType, c, "/Topic" );

							// create a delegate to the PublishAction method of the publisher
							MethodInfo publisherInvoke = publisherType.GetMethod( "PublishAction" );
							Delegate d = Delegate.CreateDelegate( eInfo.EventHandlerType, publisher, publisherInvoke );

							// wire up the delegate to the event
							eInfo.AddEventHandler( c, d );
							break;
						}
					}
				}
			}

			c.DoIt();
			Console.ReadLine();
		}

		public static void HandleEvent( params object[] args )
		{
			Console.Write( "Publish: ( " );

			bool first = true;
			foreach( object o in args )
			{
				Console.Write( (first ? "" : ", ") + o.ToString() );
				first = false;
			}
			Console.WriteLine( " )" );
		}

	}

	public class ActionPublisher<T>
	{
		public ActionPublisher( object sender, string topic )
		{
			_sender = sender;
			_topic = topic;
		}
		private object _sender;
		private string _topic;

		public void PublishAction( T t )
		{
			Program.HandleEvent( new object[] { t } );
		}
	}

	public class PubEventAttribute : Attribute
	{
	}

	public class MyClass
	{
		private Random _random = new Random();

		// DoIt fires our event
		public void DoIt()
		{
			if( Event1 != null )
				Event1( _random.Next() );
		}

		[PubEvent]
		public event Action<int> Event1;

	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
Developer with over twenty years of coding for profit, and innumerable years before that of doing it at a loss.

Comments and Discussions