I created a very simple event publisher and it looks like this.
public class EventPublisher
{
private readonly IList<Func<IHandle>> _subscribers;
public EventPublisher(IList<Func<IHandle>> subscribers)
{
_subscribers = subscribers;
}
public void Publish<TPayload>(TPayload payload)
where TPayload : class
{
var payloadHandlers = _subscribers.OfType<Func<IHandle<TPayload>>>();
foreach (var payloadHandler in payloadHandlers)
{
payloadHandler().Handle(payload);
}
}
}
Here is what I have to publish messages.
var subscribers = new List<Func<IHandle>> {() => new SomeHandler()};
var eventPublisher = new EventPublisher(subscribers);
eventPublisher.Publish(new SomeMessage { Text = "Some random text..." });
The issue I’m having is that publishing a message isn’t finding any handlers that can handle the payload. This makes sense because I registered my subscribers as Func<IHandle> instead of Func<IHandle<T>>.
The interface my handler classes are inheriting from is from Caliburn.Micro.EventAggregator and it looks like this.
public interface IHandle {}
public interface IHandle<TMessage> : IHandle {
void Handle(TMessage message);
}
What must the type of _subscribers be to handle the IHandle<> where the generic type can be any concrete type?
Assuming you’re using .NET 4, I’d expect this to work:
then to get covariance:
That lets you subscribe with any sequence of things compatible with
Func<IHandle>. Note that it does change the semantics significantly, in that the set of subscribers will be fixed after construction. Personally I’d regard that as a good thing, but it may not suit you.Alternatively, does the
EventPublisheritself have to work with multiple types? Could you make itEventPublisher<T>and useIHandle<T>everywhere, makingPublishnon-generic? This may or may not be feasible based on how you want to use this – both options make sense.