Created
January 5, 2016 08:29
-
-
Save RhysC/ca18af47a9f4926d8ab5 to your computer and use it in GitHub Desktop.
Execute/Dispatch/Call all available methods on the object that can handle the parameter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void Main() | |
{ | |
new MyObject().Dispatch(new Bar()); | |
/* OUTPUT: | |
Easy more specific target | |
Hitting the Bar | |
Fooing it up | |
Easy target | |
*/ | |
} | |
// Define other methods and classes here | |
public class MyObject | |
{ | |
private void Handle(object x) | |
{ | |
"Easy target".Dump(); | |
} | |
private void Handle(IFoo theInterface) | |
{ | |
"Easy more specific target".Dump(); | |
} | |
private void Handle(Foo foo) | |
{ | |
"Fooing it up".Dump(); | |
} | |
private void Handle(Bar bar) | |
{ | |
"Hitting the Bar".Dump(); | |
} | |
private void Handle(Foo foo, Bar bar) | |
{ | |
throw new Exception("I should not be hit, do not have a single parameter"); | |
} | |
private void Handle(string theString) | |
{ | |
throw new Exception("I should not be hit, my parameter is of the wrong type"); | |
} | |
} | |
public interface IFoo { } | |
public class Foo : IFoo { } | |
public class Bar : Foo { } | |
public static class DispatcherEx | |
{ | |
//Will execute all methods that are called "Handle" take a sinlge parameter that can be considered T | |
public static void Dispatch<T>(this object self, T parameter) | |
{ | |
var handlers = self.GetType().GetMethods(BindingFlags.NonPublic | BindingFlags.Instance) | |
.Where(m => m.Name == "Handle" && m.GetParameters().Count() == 1) | |
.ToDictionary(m => m.GetParameters().Single().ParameterType, | |
m => (Action<T>)(e => m.Invoke(self, new object[] { e }))); | |
// Dispatch to all matching methods (not just most-specific) | |
var paramType = parameter.GetType(); | |
var suitableTypes = paramType.GetInterfaces().Concat(GetBaseClasses(paramType)); | |
foreach (var suitableType in suitableTypes.Where(suitableType => handlers.ContainsKey(suitableType))) | |
{ | |
handlers[suitableType](parameter); | |
} | |
} | |
private static IEnumerable<Type> GetBaseClasses(Type type) | |
{ | |
for (var current = type; current != null; current = current.BaseType) | |
yield return current; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This may now be redundant with
objectContaining
http://jasmine.github.io/2.0/introduction.html#section-Partial_Matching_with_<code>jasmine.objectContaining<\code>