Using Redis with ASP.NET Web API

I have followed the recommendations here for using ServiceStack.Redis with Web API 2 and AutoFac dependency injection, i.e.

protected void Application_Start()
{
    ClientsManager = new PooledRedisClientManager(RedisUri);
...   

private void ConfigureDependencyResolver(HttpConfiguration configuration)
{
    var builder = new ContainerBuilder();

    builder.RegisterType<MyRedisRepository>()
        .As<IMyRedisRepository>()
        .PropertiesAutowired()
        .InstancePerRequest();

    builder.Register(c => ClientsManager.GetClient()).InstancePerRequest();
...   

However the following exception is periodically being thrown: “System.TimeoutException, Redis Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use.”

The ServiceStack documentation says that “Client Managers are connection factories which is ideally registered as a Singleton either in your IOC or static classes”. In this case, should the ContainerBuilder register the clients manager as a singleton instead?, i.e.:

    builder.Register(c => ClientsManager.GetClient()).SingleInstance();

This exception is due to the Client not being released back into the pool after it’s used.

You should only be registering the ClientsManager as a singleton in the IOC, e.g:

builder.Register<IRedisClientsManager>(c => 
    new PooledRedisClientManager(RedisUri)).SingleInstance();

Then resolving the client whenever you need it and dispose of it when you’re done with it, e.g. with a using {} statement.

public IRedisClientsManager RedisManager { get; set; }

public void Method()
{
    using (var redis = RedisManager.GetClient())
    {
         //use redis...
    }
}

When the redis client is disposed it gets released back into the pool.

To reduce the boilerplate of accessing Redis and ensuring it’s properly disposed you can adopt a lazy property in a base class, e.g:

public abstract class ServiceBase : IDisposable
{
    public virtual IRedisClientsManager RedisManager { get; set; }

    private IRedisClient redis;
    public virtual IRedisClient Redis
    {
        get { return redis ?? (redis = RedisManager.GetClient()); }
    }

    public override void Dispose()
    {
        base.Dispose();

        if (redis != null)
            redis.Dispose();
    }
}

Where your sub classes can now just access base.Redis whenever it needs access to a new Redis instance where the Dispose() method takes care of releasing the instance back into the pool when the Service is disposed.

Perfect - thanks very much!