-1

I have ASP.Net Core 2.1 app. Need to use RedisCache as Cache.

This is how my methods look to add an item to Cache.

public class RedisCache : ICache<Customer> //custom interface
{
    #region Private

    private readonly IConfiguration _configuration;
    private readonly IDatabase _cache;
    private readonly ConnectionMultiplexer _connection;
    private readonly IRedisTypedClient<Customer> _redisClient;

    #endregion Private

    #region Ctor

    public RedisCache(IConfiguration configuration, IRedisTypedClient<Customer> redisClient)
    {
        _configuration = configuration;
        _connection = ConnectionMultiplexer.Connect(configuration.GetSection("AWS:Cache")["Redis:Server"]);
        _cache = _connection.GetDatabase();
        _redisClient = redisClient;
    }

    #endregion Ctor

    public async Task<Customer> AddItem(Customer item)
    {
        try
        {
            await Task.Run(() => _redisClient.GetAndSetValue(item.Id, item)).ConfigureAwait(false);
            return item;
        }
        catch (Exception ex)
        {
            Logger.Log(ex, item);
            return null;
        }
    }
}

Dependency Registration

 services.AddScoped<IRedisTypedClient<Customer>>(); //DI Registration

When the app runs, it throws the error

Unable to resolve service for type 'ServiceStack.Redis.Generic.IRedisTypedClient

So tried to register the DI as

services.AddScoped<IRedisTypedClient<Customer>>(di => new RedisTypedClient);

but nothing such found & compiler throws build error.

How to register this IRedisTypedClient dependency?

Thanks!

Kgn-web
  • 7,047
  • 24
  • 95
  • 161

1 Answers1

1

The last bit of code is closer to what you need, but it's fairly obvious why that's throwing a compile time error. You're not including a generic type param and the parenthesis are missing, and even then, that type almost certainly must take some parameters in the constructor, which you're not providing. It should look something like:

services.AddScoped<IRedisTypedClient<Customer>>(p =>
{
    // Use `p` to get services, config values etc. For example:
    // var config = p.GetRequiredService<IConfiguration>();
    return new RedisTypedClient<Customer>(someParam);
}

That said, for cache, you shouldn't be using Redis directly. You should be injecting IDistributedCache and then including the Redis cache provider:

services.AddStackExchangeRedisCache(options =>
{
    options.Configuration = "localhost";
    options.InstanceName = "SampleInstance";
});
Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
  • Agree on #2 point. but wondering why ? Can you please add thoughts on the same – Kgn-web Sep 30 '19 at 13:36
  • the reason I had to opt this way because `IDistributedCache`doesn't have the equivant number of methods to deal with Cache as `IRedisTypedClient` – Kgn-web Sep 30 '19 at 13:37
  • Because it abstracts the specific caching implementation. If you depend on IDistributedCache, you can use whatever underlying provider you like whenever and even different providers in different environments (use memory cache in development, for example). If you depend on Redis client directly, then you can only ever use Redis, in all environments. – Chris Pratt Sep 30 '19 at 13:39
  • It has all you need, and all you should be using as part of standard app code. More advanced scenarios should be happening in a worker service or something. – Chris Pratt Sep 30 '19 at 13:41
  • Thanks! but trying to understand further. What you in the post is service layer class while my API communicates via contracts. so the UI layer or whosoever is making use of Caching in the app would have no clue what caching mechanism behind. Your thoughts! – Kgn-web Sep 30 '19 at 13:49
  • I'm not sure what you mean. If the UI layer is the one caching, then it definitely *does* need knowledge of how that caching is happening. In fact, that is the whole point. Every layer below that should only be using abstractions. It's the job of the final user-facing layer to provide concrete implementations. – Chris Pratt Sep 30 '19 at 14:06
  • Let me put the use case, all the Get/Fetch operation should be from Cache server while others would go to the database. if the `API HttpGet` is called then the service layer would fetch the data from Cache. And It would be service layer who would be knowing what Cache mechansim is underlying. Possible at some point I don't want to have cache in place in that case if I go this way the UI layer would not be disturbed which I think is the ideal case, Your thoughts? Thanks! – Kgn-web Sep 30 '19 at 14:14
  • No, that's not ideal. Again, the outermost layer is responsible for implementation. All inner layers use abstractions. The fact that the service layer is caching, may be an implementation detail of the service layer, but the cache itself belongs to the user-facing layer. – Chris Pratt Sep 30 '19 at 14:43