Code Snippet: Adding Dispose without IDisposable

Written by Troy Howard

11 November 2010

The topic of implementing IDisposable within Lucene.Net comes up a lot. While I'm all for it, there are reasons why it hasn't be done yet.

This is an alternative technique that allows using Dispose without implementing IDisposable directly.

This example uses a wrapper class, which does implement IDisposable, and allows the user to inject a custom action to happen when Dispose is called. It's a bit more fragile than directly implementing IDisposable but can be effective if done correctly.

 1using System;
 2using Lucene.Net.Index;
 3 
 4namespace Lucene.Net.Extensions
 5{
 6    public class Disposable<T> : IDisposable
 7    {
 8        public Disposable() { }
 9        public Disposable(T entity, Action<T> disposeAction)
10        {
11            Entity = entity;
12            DisposeAction = disposeAction;
13        }
14 
15        public T Entity { get; set; }
16        public Action<T> DisposeAction { get; set; }
17 
18        public void Dispose()
19        {
20            if (default(Action<T>) != DisposeAction)
21                DisposeAction(Entity);
22        }
23 
24    }
25 
26    public static class DisposableExtensions
27    {
28        public static Disposable<T> AsDisposable<T>(this T entity, Action<T> disposeAction)
29        {
30            return new Disposable<T>(entity, disposeAction);
31        }
32    }
33 
34    public class LuceneDisposableExample
35    {
36        public void Example()
37        {
38            string pathToIndex = @"C:\lucene\example\index";
39 
40            using (var disposableReader = IndexReader.Open(pathToIndex, true).AsDisposable(a => a.Close()))
41            {
42                var reader = disposableReader.Entity;
43 
44                // .. whatever you want here... 
45            }
46        }
47    }
48}

This is available as a Gist here: https://gist.github.com/thoward/673545