In the last post I discussed the Multiton pattern and this post continues the theme of non-GoF patterns by looking at Object Pool, another specialised Singleton. The purpose of this pattern is to re-use object instances to avoid creation / destruction. My mnemonic this time is a Car Pool which is just a collection of cars for my purposes:
public sealed class Car
{
    public Car(string registration)
    {
        this.Registration = registration;
    }
    public string Registration
    {
        get;
        set;
    }
    public override string ToString()
    {
        return this.Registration;
    }
}The pool implementation also uses weak references to handle garbage collected cars which have not been explicitly returned to the pool:
using System;
using System.Collections.Generic;
using System.Linq;
public sealed class CarPool
{
    private static CarPool _pool = new CarPool();
    private CarPool()
    {
        this.Cars = new Dictionary<Car, WeakReference>();
    }
    public static int Availability
    {
        get
        {
            int value = 0;
            lock (_pool)
            {
                value = _pool.Cars.Where(x => null == x.Value || !x.Value.IsAlive).Count();
            }
            return value;
        }
    }
    private Dictionary<Car, WeakReference> Cars
    {
        get;
        set;
    }
    public static void Add(params Car[] cars)
    {
        foreach (var car in cars)
        {
            lock (_pool)
            {
                _pool.Add(car);
            }
        }
    }
    public static Car Get()
    {
        Car result = null;
        if (0 < CarPool.Availability)
        {
            lock (_pool)
            {
                var item = _pool.Cars.Where(x => null == x.Value || !x.Value.IsAlive).FirstOrDefault();
                var value = new WeakReference(item.Key);
                _pool.Cars[item.Key] = value;
                result = (Car)value.Target;
            }
        }
        return result;
    }
    public static void Return(Car car)
    {
        if (null == car)
        {
            throw new ArgumentNullException("car");
        }
        lock (_pool)
        {
            _pool.Cars[car] = null;
        }
    }
    private void Add(Car car)
    {
        this.Cars.Add(car, new WeakReference(null));
    }
}Here is a test which verifies the expected behaviour:
using Xunit;
public sealed class ObjectPoolFacts
{
    [Fact]
    public void car_pooling()
    {
        Car one = new Car("ABC 111");
        Car two = new Car("ABC 222");
        CarPool.Add(one, two);
        Car first = CarPool.Get();
        Assert.Same(one, first);
        Car second = CarPool.Get();
        Assert.Same(two, second);
        Assert.Null(CarPool.Get());
        CarPool.Return(first);
        CarPool.Return(second);
        second = CarPool.Get();
        Assert.Same(one, second);
    }
}
