I'm a little confused how to implement Dispose pattern correctly.
I have a class:
public class DomainActions : IDomainActions, IDisposable
{
private HttpClient _client;
public DomainActions(string baseAddress, string token)
{
_client = new HttpClient();
_client.BaseAddress = new Uri(baseAddress);
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
}
public async Task<List<DomainDto>> GetDomainListAsync()
{
var requestStream = await _client.GetAsync("domains");
var requestString = await requestStream.Content.ReadAsStringAsync();
return ParseDomainListResponse(requestString);
}
as I understand, I have to allocate _client
public class DomainActions : IDomainActions
{
//...
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private bool _disposed = false;
public virtual void Dispose(bool disposing)
{
if (_disposed) return;
if (disposing)
{
if (_client != null)
{
_client.Dispose();
_client = null;
}
}
_disposed = true;
}
}
my implemetation is correct, is it enough?
You are not showing us where you create _client
, but let's figure out it is done in the constructor.
You are disposing the object correctly. For reference, this is the Visual Studio snippet for a complete disposal:
#region IDisposable Support
private bool disposedValue = false; // To detect redundant calls
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// TODO: dispose managed state (managed objects).
}
// TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
// TODO: set large fields to null.
disposedValue = true;
}
}
// TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
// ~A() {
// // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
// Dispose(false);
// }
// This code added to correctly implement the disposable pattern.
public void Dispose()
{
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(true);
// TODO: uncomment the following line if the finalizer is overridden above.
// GC.SuppressFinalize(this);
}
#endregion
If your unmanaged resources do not require special cleanup and can be represented by handles, you should use SafeHandles
which are less error prone and more concise. For further information, please have a look at Implement a Dispose Method.