Search code examples
c#.netdispose

Only dispose of initialized objects?


I have an API wrapper that has a series of properties that are initialized on their first use. When the class's Disposed method is called, it disposes of all of the other classes it's storing. However, there is a good chance only one or two of these other classes have been initialized anyways. If these classes aren't already initialized, the Dispose method actually ends up initializing them and them disposing them. This is massively resource and time intensive, but I cannot think of a method to remedy it.

Here's the class.

public class SalesForceApi : ISalesForce, IDisposable
{
    public Logger Logger = LogManager.GetCurrentClassLogger();

    private IAccounts _accounts;
    private IAttachments _attachments;
    private ICases _cases;
    private IContacts _contacts;
    private IGroups _groups;
    private IRecordTypes _recordTypes;
    private IUsers _users;

    public IAccounts Accounts => _accounts ?? (_accounts = new Accounts());

    public IAttachments Attachments => _attachments ?? (_attachments = new Attachments());
    public ICases Cases => _cases ?? (_cases = new Cases());
    public IContacts Contacts => _contacts ?? (_contacts = new Contacts());
    public IGroups Groups => _groups ?? (_groups = new Groups());
    public IRecordTypes RecordTypes => _recordTypes ?? (_recordTypes = new RecordTypes());
    public IUsers Users => _users ?? (_users = new Users());

    public SalesForceApi()
    {

    }

    public void Dispose()
    {
        Logger.Trace("Disposing of Acccounts...");
        Accounts.Dispose();
        Logger.Trace("Disposing of Attachments...");
        Attachments.Dispose();
        Logger.Trace("Disposing of Cases...");
        Cases.Dispose();
        Logger.Trace("Disposing of Contacts...");
        Contacts.Dispose();
        Logger.Trace("Disposing of Groups...");
        Groups.Dispose();
        Logger.Trace("Disposing of RecordTypes...");
        RecordTypes.Dispose();
        Logger.Trace("Disposing of Users...");
        Users.Dispose();
    }
}

And here is what the resulting log looks like:

SalesForceApi_v1.SalesForceApi::Disposing of Acccounts...
SalesForceApi_v1.Requests.RequestBase::Logging into SalesForce...
SalesForceApi_v1.Requests.RequestBase::SalesForce login successful!
SalesForceApi_v1.Requests.RequestBase::Logging out of SalesForce.
SalesForceApi_v1.SalesForceApi::Disposing of Attachments...
SalesForceApi_v1.Requests.RequestBase::Logging into SalesForce...
SalesForceApi_v1.Requests.RequestBase::SalesForce login successful!
SalesForceApi_v1.Requests.RequestBase::Logging out of SalesForce.
SalesForceApi_v1.SalesForceApi::Disposing of Cases...
SalesForceApi_v1.Requests.RequestBase::Logging into SalesForce...
SalesForceApi_v1.Requests.RequestBase::SalesForce login successful!
SalesForceApi_v1.Requests.RequestBase::Logging out of SalesForce.
SalesForceApi_v1.SalesForceApi::Disposing of Contacts...
SalesForceApi_v1.Requests.RequestBase::Logging out of SalesForce.
SalesForceApi_v1.SalesForceApi::Disposing of Groups...
SalesForceApi_v1.Requests.RequestBase::Logging into SalesForce...
SalesForceApi_v1.Requests.RequestBase::SalesForce login successful!
SalesForceApi_v1.Requests.RequestBase::Logging out of SalesForce.
SalesForceApi_v1.SalesForceApi::Disposing of RecordTypes...
SalesForceApi_v1.Requests.RequestBase::Logging into SalesForce...
SalesForceApi_v1.Requests.RequestBase::SalesForce login successful!
SalesForceApi_v1.Requests.RequestBase::Logging out of SalesForce.
SalesForceApi_v1.SalesForceApi::Disposing of Users...
SalesForceApi_v1.Requests.RequestBase::Logging into SalesForce...
SalesForceApi_v1.Requests.RequestBase::SalesForce login successful!
SalesForceApi_v1.Requests.RequestBase::Logging out of SalesForce. 

Solution

  • When disposing, don't call the methods that lazy-init; test and dispose the private member variables (_accounts, etc.).