/// <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; }
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); }