using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
namespace Avalonia.Utilities
{
///
/// Manages subscriptions to events using weak listeners.
///
public static class WeakEventHandlerManager
{
///
/// Subscribes to an event on an object using a weak subscription.
///
/// The type of the target.
/// The type of the event arguments.
/// The type of the subscriber.
/// The event source.
/// The name of the event.
/// The subscriber.
public static void Subscribe<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] TTarget, TEventArgs, TSubscriber>(
TTarget target, string eventName, EventHandler subscriber)
where TEventArgs : EventArgs where TSubscriber : class
{
_ = target ?? throw new ArgumentNullException(nameof(target));
var dic = SubscriptionTypeStorage.Subscribers.GetOrCreateValue(target);
if (!dic.TryGetValue(eventName, out var sub))
{
dic[eventName] = sub = new Subscription(dic, typeof(TTarget), target, eventName);
}
sub.Add(subscriber);
}
///
/// Unsubscribes from an event.
///
/// The type of the event arguments.
/// The type of the subscriber.
/// The event source.
/// The name of the event.
/// The subscriber.
public static void Unsubscribe(object target, string eventName, EventHandler subscriber)
where TEventArgs : EventArgs where TSubscriber : class
{
if (SubscriptionTypeStorage.Subscribers.TryGetValue(target, out var dic))
{
if (dic.TryGetValue(eventName, out var sub))
{
sub.Remove(subscriber);
}
}
}
private static class SubscriptionTypeStorage
where TArgs : EventArgs where TSubscriber : class
{
public static readonly ConditionalWeakTable