I'm currently working on a system using WCF to communicate between a Windows Service and one or multiple clients. Service is required to answer clients calls, as well as notify them of certain events, which is why I implemented a callback feature using simplified subscriber model. Callback interface has methods with various signatures and I'd like to use a single method to invoke one of them for all subscribers (placing enumerating over them and exception handling in one place). At first I tried approach with an enum containing interface methods and a switch statement to invoke particular method.
private enum CallbackFunc { Method1, Method2, Method3 }
private static void InvokeCallback(CallbackFunc callbackFunc, params object[] args)
{
foreach (var subscriber in subscribers)
{
try
{
switch (callbackFunc)
{
case CallbackFunc.Method1:
subscriber.Method1((int)args[0]);
break;
case CallbackFunc.Method2:
Foo foo = args[0] as Foo;
if (foo != null)
subscriber.Method2(foo , args.Length > 1 ? args[1] as List<Bar> : null);
break;
case CallbackFunc.Method3:
subscriber.Method3((Bar)args[0], (Baz)args[1]);
break;
}
}
catch
{
//error handling
}
}
}
This solution works, but I don't like it very much... it's missing finesse. I figured I could do it more universally using delegates, at which I failed because of different method signatures. Next step was to use reflection with the following result:
private static void InvokeCallback(System.Reflection.MethodInfo func, params object[] args)
{
foreach (var subscriber in subscribers)
{
try
{
func.Invoke(subscriber, args);
}
catch
{
//error handling
}
}
}
As you can see the code is much nicer, but I began to doubt if this is actually a better solution (for example because of a little reflection overhead, less nice function call).
public static void Method1(int a)
{
InvokeCallback(typeof(ICallback).GetMethod("Method1"), a);
InvokeCallback(CallbackFunc.Method1, a);
}
public static void Method2(Foo foo, List<Bar> bars)
{
InvokeCallback(typeof(ICallback).GetMethod("Method2"), foo, bars);
InvokeCallback(CallbackFunc.Method2, foo, bars);
}
public static void Method3(Bar bar, Baz baz)
{
InvokeCallback(typeof(ICallback).GetMethod("Method3"), bar, baz);
InvokeCallback(CallbackFunc.Method3, bar, baz);
}
I'd like to ask you which of these approaches is better or suggest a better solution. Any help will be much appreciated, thanks in advance.