Skip to content

Instantly share code, notes, and snippets.

@Antaris
Created June 9, 2018 21:56
Show Gist options
  • Save Antaris/9360633af0f9d647907178dc204491eb to your computer and use it in GitHub Desktop.
Save Antaris/9360633af0f9d647907178dc204491eb to your computer and use it in GitHub Desktop.
public class EventSubscription<TPayload> : IEventSubscription<TPayload>
{
private readonly WeakReference<NotificationDelegate<TPayload>> _notificationRef;
private readonly WeakReference<FilterDelegate<TPayload>> _filterRef;
/// <summary>
/// Initialises a new instance of <see cref="EventSubscriberBase{TEvent, TPayload}"/>
/// </summary>
/// <param name="token">The subscription token</param>
/// <param name="notification">The notification delegate</param>
/// <param name="filter">The filter delegate</param>
public EventSubscription(
SubscriptionToken token,
NotificationDelegate<TPayload> notification,
FilterDelegate<TPayload> filter = null)
{
Token = Ensure.IsNotNull(token, nameof(token));
_notificationRef = new WeakReference<NotificationDelegate<TPayload>>(
Ensure.IsNotNull(notification, nameof(notification)));
filter = filter ?? ((c) => Task.FromResult(true));
_filterRef = new WeakReference<FilterDelegate<TPayload>>(filter);
}
/// <inheritdoc />
public FilterDelegate<TPayload> OnFilterAsync
{
get
{
if (_filterRef.TryGetTarget(out FilterDelegate<TPayload> filter))
{
return filter;
}
return null;
}
}
/// <inheritdoc />
public NotificationDelegate<TPayload> OnNotificationAsync
{
get
{
if (_notificationRef.TryGetTarget(out NotificationDelegate<TPayload> notification))
{
return notification;
}
return null;
}
}
/// <inheritdoc />
public SubscriptionToken Token { get; }
}
public delegate Task<bool> FilterDelegate<TPayload>(EventContext<TPayload> context);
public delegate Task NotificationDelegate<TPayload>(EventContext<TPayload> context);
public class SubscriptionToken : DisposableAction<SubscriptionToken>
{
/// <summary>
/// Initialises a new instance of <see cref="SubscriptionToken"/>
/// </summary>
/// <param name="unsubscribe">The unsubscribe action</param>
public SubscriptionToken(Action<SubscriptionToken> unsubscribe)
: base(unsubscribe) { }
/// <summary>
/// Get sthe token used to identify this subscription
/// </summary>
public Guid Token { get; } = Guid.NewGuid();
}
[Fact]
public void OnNotification_ReturnsNullForDeadSubscriber()
{
// Arrange
var token = new SubscriptionToken(st => { });
WeakReference weak = null;
EventSubscription<object> subscription = null;
Action act = () =>
{
NotificationDelegate<object> notification = c => Task.CompletedTask;
weak = new WeakReference(notification);
subscription = new EventSubscription<object>(token,
(NotificationDelegate<object>)weak.Target);
};
// Act
act();
GC.Collect();
GC.WaitForPendingFinalizers();
// Assert
Assert.Null(subscription.OnNotificationAsync);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment