extend HttpClient

abstract-class, asynchronous, c#, httpclient

Solution

HttpClient is a thin wrapper around an `HttpMessageHandler` implementation (typically `HttpClientHandler`, which properties for features supported across most runtime implementations)

There's actually an `HttpMessageHandler` base class intended for decorators like your retry scenario, `DelegatingHandler`, which you could implement like this:

Something like:

public class RetryMessageHandler : DelegatingHandler
{
    readonly int retryCount;

    public RetryMessageHandler(int retryCount)
        : this(new HttpClientHandler(), retryCount)
    {
    }

    public RetryMessageHandler(HttpMessageHandler innerHandler, int retryCount)
        : base(innerHandler)
    {
        this.retryCount = retryCount;
    }

    public override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        HttpResponseMessage response = null;

        for (int i = 0; i<=retryCount; i++)
        {
            response = await base.SendAsync(request, cancellationToken);

            if (response.IsSuccessStatusCode)
            {
                return response;
            }
        }

        return response;
    }
}

Which you would then use like this:

HttpClient httpClient = HttpClientFactory.CreatePipeline(new HttpClientHandler(), 
    new [] { new RetryMessageHandler(3) });

var response = await httpClient.SendAsync(request);

Additionally, I'd recommend your `EmailClient` wraps/depends on HttpClient, rather than extending it. (Google "Composition vs Inheritance" for more information on why)

Problem

I'm trying to create a class that extends httpclient but still is abstract. ``` public abstract class Repository : HttpClient { public override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { //retry logic here var response = await base.SendAsync(request, cancellationToken); while (!IsValid(response)) { Attempts++; response = await Retry(request, cancellationToken); } Attempts = 0; return response; } public int Attempts { get; set; } public abstract bool IsValid(HttpResponseMessage response); public abstract Task<HttpResponseMessage> Retry(HttpRequestMessage request, CancellationToken cancellationToken); public abstract Type GetPageForUri(Uri uri); public abstract Task<object> GetItems(Uri uri); } ``` but when a subclass calls getStringAsync it does not call SendAsync in Repository ``` public class EmailClient : Repository { public override bool IsValid(HttpResponseMessage response) { return response.IsSuccessStatusCode; } public override Task<HttpResponseMessage> Retry(HttpRequestMessage request, CancellationToken cancellationToken) { return base.SendAsync(request, cancellationToken); } public override Type GetPageForUri(Uri uri) { return typeof(EmailPage); } public override async Task<object> GetItems(Uri uri) { var emails = await GetStringAsync(uri); return emails; } } ``` How what am I doing wrong? should I make a HttpClientHandler and include that with HttpClient? Ive tried to read about virtual if that makes any diffrent. but i dont get it why it does not get called. Can anyone help me?

Original source