I’m facing an unexpected failure in type checking within my C# event bus system. Despite implementing interfaces and generics, the type check integrationEventHandler is IIntegrationEventHandler<T>
is not behaving as expected during runtime. Consequently, the HandleAsync
method isn’t invoked as intended.
I utilize marker interfaces throughout the codebase for event handling:
public interface IIntegrationEvent;
public interface IIntegrationEventHandler;
public interface IIntegrationEventHandler<in T> : IIntegrationEventHandler where T : IIntegrationEvent
{
Task HandleAsync(T @event, CancellationToken cancellationToken = default);
}
public interface IEventBus
{
Task PublishAsync<T>(T @event, CancellationToken cancellationToken = default) where T : IIntegrationEvent;
void Subscribe<T, THandler>() where T : IIntegrationEvent where THandler : IIntegrationEventHandler<T>;
}
public sealed class InMemoryEventBusClient : IEventBus
{
private readonly IServiceProvider _serviceProvider;
public InMemoryEventBusClient(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public async Task PublishAsync<T>(T @event, CancellationToken cancellationToken = default) where T : IIntegrationEvent
{
await InMemoryEventBus.Instance.PublishAsync(@event, cancellationToken);
}
public void Subscribe<T, THandler>() where T : IIntegrationEvent where THandler : IIntegrationEventHandler<T>
{
var handler = ActivatorUtilities.CreateInstance<THandler>(_serviceProvider);
InMemoryEventBus.Instance.Subscribe(handler);
}
}
Within the InMemoryEventBus
class, the type check within the PublishAsync
method is failing unexpectedly:
public sealed class InMemoryEventBus
{
private readonly Dictionary<string, List<IIntegrationEventHandler>> _handlersDictionary = new Dictionary<string, List<IIntegrationEventHandler>>();
public async Task PublishAsync<T>(T @event, CancellationToken cancellationToken = default) where T : IIntegrationEvent
{
var eventType = @event.GetType().FullName;
if (eventType == null)
{
return;
}
foreach (var integrationEventHandler in _handlersDictionary[eventType])
{
if (integrationEventHandler is IIntegrationEventHandler<T> handler)
{
await handler.HandleAsync(@event, cancellationToken); // Type check fails here
}
}
}
public void Subscribe<T>(IIntegrationEventHandler<T> handler) where T : IIntegrationEvent
{
var eventType = typeof(T).FullName;
if (eventType is null)
{
return;
}
if (!_handlersDictionary.TryGetValue(eventType, out var handlers))
{
handlers = new List<IIntegrationEventHandler>(); // Issue: Creating a list without specifying its type
_handlersDictionary.Add(eventType, handlers);
}
handlers.Add(handler);
}
}
I’ve double-checked my code, and everything seems correct logically. Could someone please help me understand why this type check is failing? Any insights or suggestions would be greatly appreciated. Thank you!