Note: Title is for one question but I actually have 3 questions to ask.
I am using Autofac DI container to resolve dependencies.
If there are any other improvements that can be made to this code, please suggest.
I have already went through the following links:
Implementing IDisposable correctly
Implementing a Dispose method
IDisposable Part 1
Consider the following code:
Interface: IHttpClient
public interface IHttpClient : IDisposable
{
HttpRequestHeaders DefaultRequestHeaders { get; set; } // Question 1
Uri BaseAddress { get; set; }
Task<HttpResponseMessage> PostAsync(string uri, HttpContent httpContent);
}
Class: HttpClientAdaptor
internal HttpClientAdaptor : IHttpClient
{
private HttpRequestHeaders _defaultRequestHeaders;
private bool _disposed = false;
public HttpRequestHeaders DefaultRequestHeaders
{
get
{
if (_defaultRequestHeaders == null)
_defaultRequestHeaders = new HttpClient().DefaultRequestHeaders;
return _defaultRequestHeaders;
}
set
{
if (value != null)
_defaultRequestHeaders = value;
}
}
public Uri BaseAddress { get; set; }
private async Task<HttpResponseMessage> PostAsync(Uri uri, HttpContent httpContent, CancellationToken cancellationToken)
{
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, uri)
{
Content = httpContent
};
return await new HttpMessageInvoker(new HttpClientHandler()).SendAsync(request, cancellationToken); // Question 2
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
_defaultRequestHeaders = null;
BaseAddress = new Uri(); // Question 3
}
_disposed = true;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
Consider the following class, interface IHttpClient
and // Question 1
:
class DS
{
private IHttpClient _apiClient;
public class DS(/*other dependencies*/, IHttpClient apiClient)
{
_apiClient = apiClient;
}
// At somepoint I need to perform the following operation
private void SomeMethod(string hostname, /*other params*/)
{
_apiClient.BaseAddress = new Uri(hostName);
_apiClient.DefaultRequestHeaders.Accept.Clear(); // this line throws exception as "DefaultRequestHeaders" is null
_apiClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
}
Question 1: Why does it throws a null exception, when I've already resolved the dependencies. To avoid this I have to add the following line:
_apiClient.DefaultRequestHeaders = new HttpClientAdaptor().DefaultRequestHeaders;
Is there a better way to do it, rather than using above mention code everywhere I need DefaultRequestHeader
?
Question 2: Consider the class HttpClientAdaptor
and comment // Question 2
. I need to make call to the SendAsync()
. Is this the correct way or should I inherit the class HttpMessageInvoker
. Or Is there a third way to do it?
Question 3: Consider the class HttpClientAdaptor
and comment // Question 3
. Is this the right way to dispose managed code. If it is then how should I dispose property BaseAddress
? And if not, please suggest the right way. And of course current code is giving compile time error for obvious reasons.