Prevent JsonHttpClient from disposing the HttpClient

Hi,

One of our ServiceStack services uses the Service Gateway pattern to consume another remote ServiceStack service.
For this, we have been using the JsonHttpClient.

Because we need to pass along the HTTP Headers the API key from the current HTTP request, we scope our JsonHttpClient instance to the request and to avoid the performance cost of creating new HTTP connections per request, we have a single HttpClient instance that we pass to the JsonHttpClient constructor.

Our code looks something like:

public class ServiceGatewayFactory : ServiceGatewayFactoryBase
{

    static Dictionary<Assembly, Func<IRequest, IServiceGateway>> gatewayFactories = new Dictionary<Assembly, Func<IRequest, IServiceGateway>>();

    // ...
   
    public static void RegisterGatewayFactory(string baseUrl, Assembly assembly)
    {
        var msgHandler = new HttpClientHandler
        {
            AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
        };

        var httpClient = new HttpClient(msgHandler, disposeHandler: false)
        {
            BaseAddress = new Uri(baseUrl)
        };

        gatewayFactories[assembly] = req => new JsonHttpClient(baseUrl)
        {
            // HttpClient should not be disposed at it is a singleton
            SkipHttpClientDispose = true,
            HttpClient = httpClient,
            RequestFilter = msg =>
            {
                msg.AddBearerToken(req?.GetApiKey()?.Id);
            }
        };
    }
}

I couldn’t find a way to avoid the JsonHttpClient from disposing the underlying HttpClient.
At the moment, I have embedded JsonHttpClient code and modified it, hence the SkipHttpClientDispose property.

Modification is

public void Dispose()
    {
        if (!SkipHttpClientDispose)
        {
            HttpClient?.Dispose();
            HttpClient = null;
        }
    }

Is there a more elegant way to achieve this or should the JsonHttpClient expose something like above ?

You can clear out the injected HttpClient before it’s disposed:

client.HttpClient = null;
1 Like

I initially disregarded this option as I didn’t see what hook I could use until I realised I simply needed to implement IDisposable on the gateway factory to perform this cleanup task.

Much better, Thanks @mythz