Consider the following code:
public interface IEventHandler<in T> where T : IEvent
{
void Execute(T @event);
}
For these handlers I implement some concrete handler-subclasses:
public class SomeEventHandler : IEventHandler<SomeEvent>
{
public void Execute(SomeEvent @event) { /* ... */ }
}
Now I have a factory to retrieve the corresponding handler of an event:
public class EventHandlerFactory : IEventHandlerFactory
{
public IEventHandler<T> Create<T>(T @event) where T : IEvent
{
// What to do in here?
}
}
I tried to check the type of the event and then return the corresponding handler, but of course the type-system denies that:
if(@event is SomeEvent)
{
return (IEventHandler<T>) new SomeEventHandler();
}
I wouldn't do this so hacky, but I wonder how to allow the code to make that interface with the Create<T>
possible.
EDIT: When I loop through an enumarable of events the T is treated like IEvent so the type-system will throw an exception:
var events = IEnumarable<IEvent>() { /* ... */ };
foreach (var @event in events)
{
var eventHandler = eventHandlerFactory.Create(@event);
}
The Create(T @event)
-method will throw an exception because T is an IEvent and not the concrete type. I could solve it using (dynamic) @event
but is not what I really want to do.