Neat Disposal Pattern (cont)

Further to my previous post about a Neat Disposal Pattern that I liked, my friend Ollie has taken it a step further.

Please see: http://awkwardcoder.blogspot.co.uk/2012/10/using-compositedisposable-in-base.html

Advertisements

Owned without Owned<> – Part 1

Our neverending quest to make our code neater and tidier continues.

“Given a screen in our application, when the screen closes, make sure everything has been disposed.”

Seems reasonable.

When using a DI container such as Autofac, it seems like a good idea to make the most of its powerful features. If we create the screen is its own child container / lifetime scope, then disposing of that child container disposes the screen and all other objects that it resolved (or that they resolved and so on).

This works very nicely and viewing the app under the memory profiler magnifying glass confirms that everything is being cleared away nicely.

Owned<T>

The syntax for creating the Child Container in AutoFac is by injecting the object you want wrapped (for example the screen) inside an Owned<T>. For more details, see the AutoFac Documentation or Nicholas Blumhardt’s “An Autofac Lifetime Primer”.

Whilst Owned is without doubt powerful and useful, it does has the slight drawback that the fact that an object is Owned can leak out of your component.

So for example, let’s say you are using a strategy pattern to create different Screens, like this:


// Our example Strategies look like this:
public interface IStrategy
{
     IScreen GetScreen();
}

// Here's a strategy that returns Red Screens
public class RedStrategy : IStrategy
{
    private Func<RedScreen> _redScreenFactory;

    // Inject our factory
    public RedStrategy(Func<RedScreen> redScreenFactory)
    {
        _redScreenFactory = redScreenFactory;
    }

    public IScreen GetScreen()
    {
        return _redScreenFactory();
    }
}

You can imagine having several different types of strategies returning, say, Blue and Green screens.

Anyway, let’s say that Red Screens create lots of children and are particularly prone to leaking memory. It would be nice to wrap them in an Owned.

However, what does our strategy return to the consumer?


public class RedStrategy : IStrategy
{
    // Our factory now creates Owned<RedScreen>
    private Func<Owned<RedScreen>> _redScreenFactory;

    // Inject our factory
    public RedStrategy(Func<Owned<RedScreen>> redScreenFactory)
    {
        _redScreenFactory = redScreenFactory;
    }

    public IScreen GetScreen()
    {
        var ownedRedScreen = _redScreenFactory();
        return // ...?
    }
}

If we return ownedRedScreen.Value then we are losing the reference to the child container. This means that we can’t dispose it and clean up all of the contents.

On the other hand, if we change the IStrategy interface to this:

Owned<IScreen> GetScreen()

…then we are forcing all IStrategy implementations to wrap their IScreens in a child container. We are also leaking the fact that they are Owned the consumer and it must now handle Owned<IScreen>.

(This is not to even mention that Owned<RedScreen> can’t be cast to Owned<IScreen> either).

I’ll explain a couple of solutions we came up with – one neat, and one very neat (imho of course :-))

Neat Disposal Pattern

You know when you’ve been a c# developer too long when seeing a slightly neater and elegant disposal pattern gets you excited.

If you’ve been doing things properly, then you’ll already have components that are IDisposable because they need to release references (to aid garbage collection), unhook event handlers, dispose RX subscriptions  and clean up after themselves.

    public class MyComponent : IDisposable
    {
        // ...

        public void Dispose()
        {
            // Clean up component
        }
    }

Old School

Quite often, you’ll have sub-components that are also IDisposable and you need to make sure you dispose of those when you are disposed (presuming you’re responsible for their lifetime).

You could just fill your Dispose () method with individual calls to each of the IDisposables you hold. Straightforward if a little verbose.

    public class MyComponent : IDisposable
    {
        private ISubComponentA _a;
        private ISubComponentB _b;
        private ISubComponentC _c;

        public MyComponent(
            ISubComponentA a, 
            ISubComponentB b, 
            ISubComponentC c)
        {
            _a = a;
            _b = b;
            _c = c;
        }

        public void Dispose()
        {
            // Clean up component
            _a.Dispose();
            _b.Dispose();
            _c.Dispose();
        }
    }

Middle School

Or you might hold a List and add to it everything that needs disposing. Then in Dispose () you can loop over the list and dispose of everything. A bit neater.

    public class MyComponent : IDisposable
    {
        private List<IDisposable> _disposables = new List<IDisposable>(); 
        
        private ISubComponentA _a;
        private ISubComponentB _b;
        private ISubComponentC _c;

        public MyComponent(
            ISubComponentA a,
            ISubComponentB b,
            ISubComponentC c)
        {
            _a = a;
            _b = b;
            _c = c;

            _disposables.Add(_a);
            _disposables.Add(_b);
            _disposables.Add(_c);
        }

        public void Dispose()
        {
            // Clean up component
            _disposables.ForEach(d => d.Dispose());
            _disposables.Clear();
        }
    }

College

If you’re familiar with RX then you might have come across the CompositeDisposable to which you add IDisposables and then at some point simply dispose the CompositeDisposable. It takes care of disposing its contents.

using System.Reactive.Disposables;

    public class MyComponent : IDisposable
    {
        CompositeDisposable _compositeDisposable = new CompositeDisposable();

        private ISubComponentA _a;
        private ISubComponentB _b;
        private ISubComponentC _c;

        public MyComponent(
            ISubComponentA a,
            ISubComponentB b,
            ISubComponentC c)
        {
            _a = a;
            _b = b;
            _c = c;

            _compositeDisposable.Add(_a);
            _compositeDisposable.Add(_b);
            _compositeDisposable.Add(_c);
        }

        public void Dispose()
        {
            // Clean up component
            _compositeDisposable.Dispose();
        }
    }

University?

So the final neatening up that I saw recently was this.

You have a base class called DisposableObject. It has a method called AddDisposable(IDisposable x) which adds the x to a private CompositeDisposable.

DisposableObject then disposes of its CompositeDisposable in its Dispose method.

    public interface IDisposableObject: IDisposable
    {
        void AddDisposable(IDisposable disposableObject);
    }

    public class DisposableObject : IDisposableObject
    {
        CompositeDisposable _compositeDisposable = new CompositeDisposable();

        public void AddDisposable(IDisposable disposableObject)
        {
            _compositeDisposable.Add(disposableObject);
        }

        public virtual void Dispose()
        {
            _compositeDisposable.Dispose();
        }
    }

You then derive from DisposableObject and the idea is to pass any objects that we need disposing to the base class.

But here’s the neat bit.

Rather than calling the base class’ AddDisposable method directly, write an extension method that looks like this:

    public static class DisposableExtensions
    {
        public static T DisposeWith<T>(this T source, IDisposableObject target) where T : IDisposable
        {
            target.AddDisposable(source);
            return source;
        }
    }

This means that now the code can look like this:

    public class MyComponent : DisposableObject
    {
        private ISubComponentA _a;
        private ISubComponentB _b;
        private ISubComponentC _c;

        public MyComponent(
            ISubComponentA a,
            ISubComponentB b,
            ISubComponentC c)
        {
            _a = a;
            _b = b;
            _c = c;

            _a.DisposeWith(this);
            _b.DisposeWith(this);
            _c.DisposeWith(this);
        }
    }

Very readable and very neat and tidy.

It means that when you make an RX subscription, instead of storing that subscription in a member variable and remembering to dispose of it later, you can do this:

            IObservable<Trade> trades = _tradeService.GetTrades();

            var subscription = trades
                .Where(t => t.TradedAmount > 1000000000.00)
                .Subscribe(HandleLargeTrade)
                .DisposeWith(this);

And I thought that that was rather nice.

My latest thoughts are whether there is a neat way to null the references too. Hmm…