예제 #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="WeakEventSubscription{TDelegateInstanceObject, TEventArgs}"/> class.
        /// </summary>
        /// <param name="eventHandler">The event handler.</param>
        /// <param name="unsubscribeFromEventAction">The delegate method that unsubscribes from the event.</param>
        public WeakEventSubscription(EventHandler <TEventArgs> eventHandler, UnsubscribeFromEventAction <TEventArgs> unsubscribeFromEventAction)
        {
            if (eventHandler == null)
            {
                throw new ArgumentNullException(nameof(eventHandler));
            }

            // Hold a weak reference to the target of the event handler - not the event handler itself, which would cause a strong reference.
            this.weakReferenceToEventHandlerTarget = new WeakReference(eventHandler.Target);

            // Create an unbound delegate to the MethodInfo for the event handler - not the event handler itself, which would cause a strong reference.
            this.unboundDelegateEventHandler = (UnboundDelegateEventHandler)Delegate.CreateDelegate(typeof(UnboundDelegateEventHandler), null, eventHandler.Method);

            // The actual event handler is a method in this class - not the event handler from the other object.
            this.eventHandler = this.InvokeEventHandler;

            this.unsubscribeFromEventAction = unsubscribeFromEventAction;
        }
예제 #2
0
        private void InvokeEventHandler(object sender, TEventArgs e)
        {
            var instanceObject = this.weakReferenceToEventHandlerTarget.Target as TDelegateInstanceObject;

            if (instanceObject != null)
            {
                this.unboundDelegateEventHandler.Invoke(instanceObject, sender, e);
            }
            else if (this.unsubscribeFromEventAction != null)
            {
                // If instance object from the weak reference has been garbage collected, then unsubscribe from the event.
                try
                {
                    this.unsubscribeFromEventAction.Invoke(this.eventHandler);
                }
                finally
                {
                    this.unsubscribeFromEventAction = null;
                }
            }
        }
        private static IWeakEventSubscription <TEventArgs> CreateWeakEventSubscription <TEventArgs>(EventHandler <TEventArgs> eventHandler, UnsubscribeFromEventAction <TEventArgs> unsubscribeFromEventDelegate) where TEventArgs : EventArgs
        {
            Type            type        = typeof(WeakEventSubscription <,>).MakeGenericType(eventHandler.Method.DeclaringType, typeof(TEventArgs));
            ConstructorInfo constructor = type.GetConstructor(new Type[] { typeof(EventHandler <TEventArgs>), typeof(UnsubscribeFromEventAction <TEventArgs>) });

            return((IWeakEventSubscription <TEventArgs>)constructor.Invoke(new object[] { eventHandler, unsubscribeFromEventDelegate }));
        }
        /// <summary>
        /// Creates a weak event subscription/handler, specifying a delegate method that can unsubscribe the event handler from the event.
        /// </summary>
        /// <typeparam name="TEventArgs">The type of the event arguments.</typeparam>
        /// <param name="eventHandler">The event handler.</param>
        /// <param name="unsubscribeFromEventDelegate">The unsubscribe from event delegate.</param>
        /// <returns>
        /// A weak event handler.
        /// </returns>
        /// <exception cref="System.ArgumentNullException">If eventHandler is null.</exception>
        /// <exception cref="System.ArgumentException">A WeakEventSubscription can only be created on instance methods.;eventHandler.</exception>
        internal static IWeakEventSubscription <TEventArgs> Create <TEventArgs>(EventHandler <TEventArgs> eventHandler, UnsubscribeFromEventAction <TEventArgs> unsubscribeFromEventDelegate) where TEventArgs : EventArgs
        {
            if (eventHandler == null)
            {
                throw new ArgumentNullException(nameof(eventHandler));
            }

            if (eventHandler.Method.IsStatic || eventHandler.Target == null)
            {
                throw new ArgumentException("A WeakEventSubscription can only be created on instance methods.", nameof(eventHandler));
            }

            IWeakEventSubscription <TEventArgs> weakEventSubscription = CreateWeakEventSubscription <TEventArgs>(eventHandler, unsubscribeFromEventDelegate);

            return(weakEventSubscription);
        }