Frage

So arbeite ich an meinem DI / IoC Container OpenNETCF.IoC und ich habe eine (angemessene bekam ) Feature-Anfrage für IDisposable Elemente in den Containern Sammlungen irgendeine Form von Lifecycle-Management hinzuzufügen.

ist meine derzeitige Überlegung, dass, da ich kein Objekt abfrage kann, ob es angeordnet gewesen ist, und ich kann nicht ein Ereignis für bekommen, wenn es gewesen ist angeordnet, dass ich irgendeine Form von Wrapper für Objekte erstellen, Entwickler will die Verwaltung der Rahmen.

Gerade jetzt Objekte mit AddNew hinzugefügt werden kann (der Einfachheit halber nehmen wir an, es gibt nur eine Überlastung und es gibt keine Add):

public TTypeToBuild AddNew<TTypeToBuild>() { ... }

Was ich erwägen eine neue Methode Hinzufügen (gut Gruppe von ihnen, aber Sie bekommen das Bild):

public DisposableWrappedObject<IDisposable> AddNewDisposable<TTypeToBuild>()
    where TTypeToBuild : class, IDisposable
{
    ...
}

Wo die DisposableWrappedObject sieht wie folgt aus:

public class DisposableWrappedObject<T>
    where T : class, IDisposable
{
    public bool Disposed { get; private set; }
    public T Instance { get; private set; }

    internal event EventHandler<GenericEventArgs<IDisposable>> Disposing;

    internal DisposableWrappedObject(T disposableObject)
    {
        if (disposableObject == null) throw new ArgumentNullException();

        Instance = disposableObject;
    }

    ~DisposableWrappedObject()
    {
        Dispose(false);
    }

    public void Dispose()
    {
        Dispose(true);
    }

    protected virtual void Dispose(bool disposing)
    {
        lock(this)
        {
            if(Disposed) return;

            EventHandler<GenericEventArgs<IDisposable>> handler = Disposing;
            if(handler != null)
            {
                Disposing(this, new GenericEventArgs<IDisposable>(Instance));
            }

            Instance.Dispose();

            Disposed = true;
        }
    }
}

Nun, wenn ein Artikel zu dem Behälter über AddNewDIsposable hinzugefügt wird, wird ein Eventhandler auch hinzugefügt, so dass, wenn es bekommt Disposed (über den Wrapper) der Rahmen aus der zugrunde liegenden Auflistung entfernt.

ich dies tatsächlich implementiert haben, und es ist die Unit-Tests vorbei, aber ich bin auf der Suche nach Meinungen darüber, wo diese gebrochen werden könnte, oder wie es gemacht werden könnte „freundlich“ zum Verbraucher Entwickler.

EDIT 1

Da es eine Frage war, wie die Entsorgung Ereignis verwendet wird, hier einige Code ist (getrimmt, was wichtig ist):

private object AddNew(Type typeToBuild, string id, bool wrapDisposables)
{
    ....

    object instance = ObjectFactory.CreateObject(typeToBuild, m_root);

    if ((wrapDisposables) && (instance is IDisposable))
    {
        DisposableWrappedObject<IDisposable> dispInstance = new
               DisposableWrappedObject<IDisposable>(instance as IDisposable);
        dispInstance.Disposing += new 
               EventHandler<GenericEventArgs<IDisposable>>(DisposableItemHandler);
        Add(dispInstance as TItem, id, expectNullId);
        instance = dispInstance;
    }

    ....

    return instance;
}

private void DisposableItemHandler(object sender, GenericEventArgs<IDisposable> e)
{
    var key = m_items.FirstOrDefault(i => i.Value == sender).Key;
    if(key == null) return;
    m_items.Remove(key);
}
War es hilfreich?

Lösung

Vielleicht bin ich etwas fehlt, aber warum neue Methoden zur API hinzufügen? Wenn ein Objekt in den Behälter gegeben wird, könnten Sie wie gegossen zu überprüfen, ob es die IDisposable und damit umgehen angemessen, wenn so.

Ich frage mich auch, wenn Sie den Destruktor benötigen. Vorausgesetzt, der Behälter ist IDisposable (wie Unity), könnten Sie einfach implementieren, um die Grund Entsorgen Muster und spart eine Menge GC-Overhead.

Einige Fragen, die anwendbar sein können:

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top