Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make an IDisposable object a class variable?

I am working with Active Directory using C#. Instantiating the PrincipalContext object seems to be expensive, so I'd like to store one in a class variable.

When using PrincipalContext as a local variable, I can use the convenient using syntax. When storing an IDisposable object in a static variable, how do I ensure the object is properly disposed of?

like image 947
Ben Aston Avatar asked Mar 14 '10 00:03

Ben Aston


2 Answers

The general pattern for this is to implement the IDisposable interface on your class. Take this example:

public class YourClass : IDisposable
{
    private OtherDisposableType yourResource;

    public YourClass()
    {
        yourResource = new OtherDisposableType();
    }

    public void Dispose()
    {
        yourResource.Dispose();
    }
}

This is, at a minimum, what you need to do.

EDIT

My previous version advocated following the finalizer pattern in all cases, which was (correctly) pointed out to be against the framework design guidelines. However, in the event that you're actually dealing with unmanaged resources (for example, you're making direct P/Invoke calls and obtaining a handle that needs to be explicitly freed) it's advisable that you create a finalizer and call Dispose within it to protect against people who consume your code and don't call Dispose:

public class YourClass : IDisposable
{
    private OtherDisposableType yourResource;

    public YourClass()
    {
        yourResource = new OtherDisposableType();
    }

    public void Dispose()
    {
        yourResource.Dispose();

        GC.SuppressFinalize(this);
    }

    ~YourClass()
    {
        Dispose();
    }
}
like image 129
Adam Robinson Avatar answered Sep 17 '22 11:09

Adam Robinson


Look at what the System.ComponentModel namespace does. Basically, the pattern I typically use is to have a collection of subcomponents, which includes everything I own that's not a 'value' - whether or not it implements IDisposable.

Then, when I Dispose() myself, I iterate over this collection and Dispose anything that implements IDisposable.

One advantage of this technique is that if an object I own starts out not being Disposable, but later adds the IDisposable interface, my class will do the right thing without ever having to change.

Also, use of a DI/IoC container can handle much of this for you.

like image 32
kyoryu Avatar answered Sep 19 '22 11:09

kyoryu