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:
var subscribers = new List<Func<IHandle<SomeMessage>>> {() => new SomeHandler()};
then to get covariance:
public EventPublisher(IEnumerable<Func<IHandle>> subscribers)
{
_subscribers = subscribers.ToList();
}
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 EventPublisher
itself have to work with multiple types? Could you make it EventPublisher<T>
and use IHandle<T>
everywhere, making Publish
non-generic? This may or may not be feasible based on how you want to use this - both options make sense.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With