Пример #1
0
        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);
            }
        }
Пример #2
0
        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);
        }
Пример #3
0
            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));
            }
Пример #4
0
        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));
            }
        }
Пример #5
0
        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);
            }
        }
Пример #6
0
        /// <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();
                }
            }
        }
Пример #7
0
 private bool AddEventHandler(ControllingObjectWrap wrap)
 {
     return(this.disposeConnections.ContainsKey(wrap) || wrap.AddEventHandler());
 }