I struggled to write a more appropriate 'title' to this question - I will try and clean it up when I have a better understanding of the solution and the correct terminology. :D
There is a pattern that is repeating in the last two projects I've been working on (the projects are both heavily event driven).
The pattern is:
public interface ISourceOfEvents {
event Action<EventInfo1> SomethingHappened1;
event Action<EventInfo2> SomethingHappened2;
{...}
}
public class SingleSourceOfEvents : ISourceOfEvents {
public event Action<EventInfo1> SomethingHappened1 = delegate { };
public event Action<EventInfo2> SomethingHappened2 = delegate { };
{...}
}
public class GroupSourceOfEvents : ISourceOfEvents {
public IList<ISourceOfEvents> SourceOfEventsGroup { get; private set; }
public event Action<EventInfo1> SomethingHappened1 = delegate { };
public event Action<EventInfo2> SomethingHappened2 = delegate { };
{...}
public GroupSourceOfEvents(IList<ISourceOfEvents> sourceOfEventsGroup) {
SourceOfEventsGroup = sourceOfEventsGroup;
foreach (var s in SourceOfEventsGroup) {
s.SomethingHappened1 += x => SomethingHappened1(x);
s.SomethingHappened2 += x => SomethingHappened2(x);
{...}
}
}
}
My question boils down to 'how do I make the constructor for GroupSourceOfEvents map the event bindings automatically?'.
Currently the code is hard to maintain because there are multiple places across the projects that new events need to be added. The ISourceOfEvents interface allows me to add the event to a central place and get compiler errors everywhere I need to add the event but I need a similar solution for the event binder mappings in the GroupSourceOfEvents - or for it to be completely dynamic.
I would like something similar to this:
// PSEUDO-CODE WARNING! :D
// PSEUDO-CODE WARNING! :D
// PSEUDO-CODE WARNING! :D
public GroupSourceOfEvents(IList<ISourceOfEvents> sourceOfEventsGroup) {
SourceOfEventsGroup = sourceOfEventsGroup;
var events = typeof(ISourceOfEvents).GetEvents();
foreach (var s in SourceOfEventsGroup) {
foreach (var e in events) {
e.AddEventHandler(s, e.GetRaiseMethod(this));
}
}
}
Half my problem is mapping the parameters together. In the currently working code (the top sample) a lambda expression is used but I'm not sure how that can be achieved using the 'style' of technique I'm using in my pseudo code (the bottom sample). The other half of my problem is that GetRaiseMethod(this) is returning MethodInfo opposed to delegate (which is what I would need to use AddEventHandler) and I'm not sure how to "get at" the delegate.
Any help would be greatly appreciated. I'm also open to different patterns or approaches that may be more standard (if this one is not).
I'm using C# and .Net 4.