I am using Notifications from MediatR for Cache Invalidation, for example Created, Updated and Deleted events for each entity in my application.
I am using some logic to add the handlers to my service collection, but the simplified and also not working version looks like this:
collection.AddTransient(
typeof(IEventHandler<UpdatedEvent<RefreshToken, RefreshTokenId>>),
typeof(UpdatedEventHandler<IRefreshTokenRepository, RefreshToken, RefreshTokenId, IRefreshTokenDto, UpdatedEvent<RefreshToken, RefreshTokenId>>));
And an example of how i would publish the notification looks like this:
await _mediator.Publish(new UpdatedEvent<RefreshToken, RefreshTokenId>(new RefreshToken(new UserId())), cancellationToken);
The implementation of the UpdatedEventHandler looks like this:
public class UpdatedEventHandler<TIRepository, TEntity, TId, TIDto, TUpdated> : IEventHandler<TUpdated>
where TUpdated : UpdatedEvent<TEntity, TId>
where TIRepository : IRepository<TEntity, TId, TIDto>
where TEntity : Entity<TId>
where TId : IdObject<TId>
where TIDto : IDto<TId>
{
private readonly TIRepository _repository;
public UpdatedEventHandler(TIRepository repository)
{
_repository = repository;
}
public Task Handle(TUpdated updatedEvent, CancellationToken cancellationToken)
{
var _cacheKeys = GetBaseCacheKeysAsync(updatedEvent);
return _repository.ClearCacheAsync(_cacheKeys);
}
private async IAsyncEnumerable<string> GetBaseCacheKeysAsync(TUpdated updatedEvent)
{
yield return await repository.EntityValueCacheKeyAsync(nameof(_repository.GetByIdAsync),
updatedEvent.Updated.Id.Value.ToString());
yield return await repository.EntityCacheKeyAsync(nameof(_repository.GetListAsync));
await foreach (var cacheKey in GetCacheKeysAsync(updatedEvent))
{
yield return cacheKey;
}
}
protected virtual IAsyncEnumerable<string> GetCacheKeysAsync(TUpdated updatedEvent)
{
throw new NotImplementedException("Override this method to add additional cache keys.");
}
}
I have tried different things, but no matter what i do, the event handler does not get called.
I did try implementing explicit classes which inherit from the updatedEventHandler and refering the generic parameters and then it worked, but thats not really what i try to achieve. Whats also weird about this is, that the registering of the event handler stayed the same, but with the inheriting class, the event handler method was called.
I was using a custom Interface IEventHandler which was inheriting from INotificationHandler. I added my event handlers as IEventHandlers to the serviceCollection, when MediatR "searched" for INotificationHandlers for my notification to publish, nothing was found because of that.