Skip to content

Instantly share code, notes, and snippets.

@simon-engledew
Created August 25, 2011 14:57
Show Gist options
  • Save simon-engledew/1170855 to your computer and use it in GitHub Desktop.
Save simon-engledew/1170855 to your computer and use it in GitHub Desktop.
Dispatch by Generic type
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Diagnostics;
using System.Threading;
namespace Ladybear
{
/// <summary>
/// Dispatches to an Action based on the first generic type parameter.
/// </summary>
public class Dispatch
{
private static Action<Exception> PreserveStackTrace;
static Dispatch()
{
Dispatch.PreserveStackTrace = (Action<Exception>)Delegate.CreateDelegate(typeof(Action<Exception>), typeof(Exception).GetMethod("InternalPreserveStackTrace", BindingFlags.Instance | BindingFlags.NonPublic));
}
private Dictionary<Type, Delegate> handlers = new Dictionary<Type, Delegate>();
public void Add<T>(Action<T> handler)
{
handlers.Add(handler.GetType().GetGenericArguments()[0], handler);
}
public void Invoke(object value)
{
Type type = value.GetType();
if (handlers.ContainsKey(type))
{
try
{
handlers[type].DynamicInvoke(value);
}
catch (TargetInvocationException e)
{
Exception innerException = e.InnerException;
if (innerException != null)
{
Trace.WriteLine(innerException.Message + Environment.NewLine + innerException.StackTrace);
Dispatch.PreserveStackTrace(innerException);
throw innerException;
}
throw;
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment