Schwachstellen in der Entlib 5 – Unity Container im Unity Container führt zu Stack Overflow Exception

Was mich jetzt, nachdem ich so richtig schön dabei bin mit der Enterprise Library 5 eine Anwendung zu schreiben ziemlich nervt, ist die Dispose Struktur von Microsoft. Ich hab festgestellt, dass wenn ich im Unity Container den UnityServiceLocator registriere eine StackOverflowException beim Dispose Aufruf kommt. Das liegt ganz einfach daran, dass der Unity Container intern beim Dispose alle Elemente durchscannt, die IDisposable implementieren und deren Dispose Methode aufruft(ist klar, macht ja auch Sinn). Aber: Jetzt kommt der in die Dispose Methode vom ServiceLocator rein, der ruft(logischerweise) dann wieder die Dispose vom UnityContainer auf, und so weiter. Mein Code:

public class Bootstrapper : IDisposable
{
    private bool isDisposed;
    private IUnityContainer container;

    ~Bootstrapper()
    {
        this.Dispose(false);
    }

    public void Run()
    {
        this.container = new UnityContainer();

        ((UnityConfigurationSection)ConfigurationManager.GetSection("unity")).Configure(this.container);
        this.container.RegisterInstance<IServiceLocator>(new UnityServiceLocator(this.container));
    }

    public void Dispose()
    {
        this.Dispose(true);
        GC.SuppressFinalize(this);
    }

    private void Dispose(bool disposing)
    {
        if (!this.isDisposed)
        {
            this.isDisposed = true;
            this.container.Dispose();
        }
    }
}

Das Problem wäre ganz einfach zu beheben wenn Microsoft im Code vom UnityContainer das Feld isDisposed gleich am Anfang der Dispose Mathode auf true setzen würde, dann käme eine solche Kettenreaktion überhaupt nicht zustande. Vielleicht merken sie´s ja noch. Aber wir müssen uns jetzt darum kümmern, dass sowas trotzdem funktioniert. Die Lösung ist sehr simpel. Im UnityContainer gibt es schon ewig die Möglichkeit einem Objekt ein anderes Verhalten zu verpassen, über die Klasse LifetimeManager. Die überschreibt das Standartverhalten mit den ganzen Dispose() aufrufen. Auf dem ServiceLocator brauchen wir ja auch nicht die Dispose() aufzurufen, weil der sowieso nur wieder die vom UnityContainer aufrufen würde, und die rufen wir ja schon auf. Also lassen wir die einfach weg indem wir den Code der bei Run ausgeführt wird in den Folgenden ändern:

public void Run()
{
    this.container = new UnityContainer();

    ((UnityConfigurationSection)ConfigurationManager.GetSection("unity")).Configure(this.container);
    this.container.RegisterInstance<IServiceLocator>(new UnityServiceLocator(this.container), new ExternallyControlledLifetimeManager());
}