Dependency injection in DbCommandInterceptor

338 views Asked by At

I am trying to add the Azure Redis Cache to my app. I am trying to do it with the interceptor, so when a query is done if the result is present in the cache I replace the result and I do one less query, otherwise I get the result of the query and I store it in the cache. Of course I am doing it only when certain table are involved. I have added the Redis Cache to my startup:

services.AddDistributedRedisCache(config =>
        {
            config.Configuration = GetAppSettingsValue("RedisConnectionString", Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"));
        });

Now I need to use it in my interceptor:

public class RedisCacheInterceptor : DbCommandInterceptor
{
    private readonly IDistributedCache _distributedCache;

    public RedisCacheInterceptor(IDistributedCache distributedCache)
    {
        _distributedCache = distributedCache;
    }
}

At this point when I try to add the interceptor to the db connection I have no idea on how to instantiate the interceptor using the dependency injection.

How should I solve this problem? Am I using the interceptor in the wrong way?

1

There are 1 answers

0
Eduard Keilholz On

This doesn't answer your question to use an interceptor, but maybe this pattern may help. Review this code:

private async Task<T> GetFromCacheOrDownloadAsync<T>(string cacheKey, Func<Task<T>> initializeFunction)
{
    bool cacheAvailable;
    try
    {
        await Connect();
        var value = await _database.StringGetAsync(cacheKey);
        if (!string.IsNullOrEmpty(value))
        {
            return JsonSerializer.Deserialize<T>(value);
        }

        cacheAvailable = true;
    }
    catch (Exception)
    {
        _logger.LogWarning("Oops, apparently your cache is down...");
        cacheAvailable = false;
    }

    var downloadedObject = await initializeFunction();
    var jsonValue = JsonSerializer.Serialize(downloadedObject);

    if (cacheAvailable)
    {
        await _database.StringSetAsync(cacheKey, jsonValue);
    }

    return downloadedObject;
}

It's a function I call to get 'something' from Redis Cache. I also pass a initialization function to call when the data is not present. So basically:

  • Get the data from cache
  • Fetch data using a different function if it doesn't exist
  • Add to cache

See this demo repo containing this very example:

https://github.com/4DotNet/WebCasts-Caching