So arbeite ich an meinem DI/IoC-Container OpenNETCF.IoC und ich habe eine (sinnvolle) Feature-Anfrage, um eine Form von Lifecycle-Management für IDisposable Elemente in den Containersammlungen hinzuzufügen.DI: Behandeln der Lebensdauer von IDisposable Objects
Mein aktuelles Denken ist, dass, da ich ein Objekt nicht abfragen kann, um zu sehen, ob es entsorgt wurde, und ich kein Ereignis abrufen kann, wenn es entsorgt wurde, dass ich eine Art Wrapper für Objekte erstellen muss dass ein Entwickler das Framework verwalten möchte.
Rechts-Objekte können jetzt mit AddNew hinzugefügt werden (der Einfachheit halber nehmen wir an, es gibt nur eine Überlastung und es gibt keine Add):
public TTypeToBuild AddNew<TTypeToBuild>() { ... }
Was ich erwägt 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 wie folgt aussieht:
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;
}
}
}
Wenn nun ein Element über AddNewDIsposable zum Container hinzugefügt wird, wird auch ein Eventhandler hinzugefügt, so dass das Framework es aus der zugrunde liegenden Sammlung entfernt, sobald es Disposed (über den Wrapper) erhält.
Ich habe dies tatsächlich implementiert und es besteht die Unit-Tests, aber ich bin auf der Suche nach Meinungen darüber, wo dies möglicherweise gebrochen wird, oder wie es für den konsumierenden Entwickler "freundlicher" gemacht werden könnte.
EDIT 1
Da es eine Frage, wie die Entsorgung Ereignis verwendet wird, hier einige Code (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);
}
Können wir Beschreibung der spezifischen Funktion erhalten eine vollere, die hinzugefügt wird? Was sind die Anwendungsfälle, für die die Leute das wollen, ist der Event-Handler für Sie als (IoC-Framework) oder als Endbenutzer? Usw. – Quibblesome
Der Anwendungsfall ist das Hinzufügen eines automatisierten Lebenszyklusmanagements. Wenn Sie ein IDisposable-Objekt zu einer Sammlung hinzufügen und später Dispose aufrufen, wird es niemals wirklich bereinigt, da der Container eine Wurzel für das Objekt enthält. Die Idee ist, dass Sie Dispose für das Objekt aufrufen können, ohne zur Sammlung zurückkehren zu müssen, um es zu finden, und dies automatisch zur Entfernung aus der Containersammlung führt. Das Ereignis wird rein intern vom Framework verwendet (es ist sogar als intern markiert, damit es nicht verwendet wird) und der Handler entfernt es aus der Sammlung. – ctacke
Ich habe die Frage aktualisiert, um die Ereignisbehandlung für Klarheit hinzuzufügen. – ctacke