public bool AddDisposeConnection(ControllingObjectWrap wrap, IDisposable disposable) { lock (this.monitor) { if (this.IsDisposed) { throw new InvalidOperationException("DisposablesHandler instance was allready disposed of."); } if (wrap == null) { throw new ArgumentNullException("wrap"); } if (disposable == null) { throw new ArgumentNullException("disposable"); } bool result = this.AddEventHandler(wrap); if (result) { if (!this.wrapDictionary.ContainsKey(wrap.Subject)) { this.wrapDictionary.Add(wrap.Subject, wrap); } this.disposeConnections.AddForwardAndReverse(wrap, disposable, this.reverseDisposeConnections); } return(result); } }
private bool RemoveAndExecuteConnection(ControllingObjectWrap wrap, bool execute) { if (wrap == null) { throw new ArgumentNullException("wrap"); } if (this.IsDisposed) { throw new InvalidOperationException("DisposablesHandler instance was allready disposed of."); } if (this.disposeConnections.Count == 0) { throw new InvalidOperationException("DisposablesHandler contains no dispose connections. Use AddDisposeConnection(...) methods."); } HashSet <IDisposable> disposables; bool result = this.disposeConnections.TryGetValue(wrap, out disposables); if (result) { foreach (IDisposable disposable in disposables) { // Remove all other connections to the item. foreach (var otherWrap in this.reverseDisposeConnections[disposable]) { if (!otherWrap.Equals(wrap)) { this.RemoveItemAndListIfEmpty(this.disposeConnections, otherWrap, disposable); } } this.reverseDisposeConnections.Remove(disposable); if (execute) { Debug.WriteLine("Disposing of \"{0}\" because \"{1}\" unloaded.", disposable, wrap.Subject); try { disposable.Dispose(); } catch (Exception ex) { Debug.WriteLine("Disposing of \"{0}\" caused an Exception:\n{1}", disposable, ex); } } } this.disposeConnections.Remove(wrap); wrap.RemoveEventHandler(); // If the dispose connections dictionary is empty now, dispose of this instance. Singleton <DisposablesHandler> .TryToDisposeOfInstance(); } return(result); }
public override bool Equals(object obj) { if (object.ReferenceEquals(this, obj)) { return(true); } ControllingObjectWrap other = obj as ControllingObjectWrap; return(other != null && object.Equals(this.Subject, other.Subject)); }
public bool RemoveAllDisposeConnectionsOf(ControllingObjectWrap wrap) { lock (this.monitor) { if (this.IsDisposed) { throw new InvalidOperationException("DisposablesHandler instance was allready disposed of."); } return(this.RemoveAndExecuteConnection(wrap, false)); } }
public bool RemoveDisposeConnection(ControllingObjectWrap wrap, IDisposable disposable) { lock (this.monitor) { if (this.IsDisposed) { throw new InvalidOperationException("DisposablesHandler instance was allready disposed of."); } if (this.disposeConnections.Count == 0) { throw new InvalidOperationException("DisposablesHandler contains no dispose connections. Use AddDisposeConnection(...) methods."); } if (wrap == null) { throw new ArgumentNullException("wrap"); } if (disposable == null) { throw new ArgumentNullException("disposable"); } HashSet <IDisposable> disposables; if (this.disposeConnections.TryGetValue(wrap, out disposables) && disposables.Remove(disposable)) { bool removeReverseConnection = true; if (disposables.Count == 0) { this.disposeConnections.Remove(wrap); wrap.RemoveEventHandler(); removeReverseConnection = !Singleton <DisposablesHandler> .TryToDisposeOfInstance(); } if (removeReverseConnection) { this.RemoveItemAndListIfEmpty(this.reverseDisposeConnections, disposable, wrap); } return(true); } return(false); } }
/// <summary> /// Removes the given item from the list in the dictionary under the given key and /// also the list itsself, if it is empty afterwards. /// </summary> /// <typeparam name="TKey">The type of the key ('object' for forward connections and 'IDisposable' for reverse).</typeparam> /// <typeparam name="TItem">The type of the item ('IDisposable' for forward connections and 'object' for reverse).</typeparam> /// <param name="dictionary">The dictionary to add the connection to (either disposeConnections or reverseDisposeConnections).</param> /// <param name="key">The key (the object to dispose along with or the disposable (in case of reverse connection)).</param> /// <param name="item">The item (the disposable or the object to dispose along with (in case of reverse connection)).</param> private void RemoveItemAndListIfEmpty <TKey, TItem>(Dictionary <TKey, HashSet <TItem> > dictionary, TKey key, TItem item) { HashSet <TItem> items = dictionary[key]; items.Remove(item); if (items.Count == 0) { dictionary.Remove(key); // If this method is used to remove a forward connection... ControllingObjectWrap wrap = key as ControllingObjectWrap; if (wrap != null) { // Remove all event handlers. wrap.RemoveEventHandler(); } } }
private bool AddEventHandler(ControllingObjectWrap wrap) { return(this.disposeConnections.ContainsKey(wrap) || wrap.AddEventHandler()); }