RaspberryIO/Unosquare.Swan/Components/MessageHubSubscriptionToken.cs
2019-12-03 18:44:25 +01:00

49 lines
1.6 KiB
C#

using System;
#if NETSTANDARD1_3
using System.Reflection;
#endif
namespace Unosquare.Swan.Components {
/// <summary>
/// Represents an active subscription to a message.
/// </summary>
public sealed class MessageHubSubscriptionToken
: IDisposable {
private readonly WeakReference _hub;
private readonly Type _messageType;
/// <summary>
/// Initializes a new instance of the <see cref="MessageHubSubscriptionToken"/> class.
/// </summary>
/// <param name="hub">The hub.</param>
/// <param name="messageType">Type of the message.</param>
/// <exception cref="System.ArgumentNullException">hub.</exception>
/// <exception cref="System.ArgumentOutOfRangeException">messageType.</exception>
public MessageHubSubscriptionToken(IMessageHub hub, Type messageType) {
if(hub == null) {
throw new ArgumentNullException(nameof(hub));
}
if(!typeof(IMessageHubMessage).IsAssignableFrom(messageType)) {
throw new ArgumentOutOfRangeException(nameof(messageType));
}
this._hub = new WeakReference(hub);
this._messageType = messageType;
}
/// <inheritdoc />
public void Dispose() {
if(this._hub.IsAlive && this._hub.Target is IMessageHub hub) {
System.Reflection.MethodInfo unsubscribeMethod = typeof(IMessageHub).GetMethod(nameof(IMessageHub.Unsubscribe),
new[] { typeof(MessageHubSubscriptionToken) });
unsubscribeMethod = unsubscribeMethod.MakeGenericMethod(this._messageType);
_ = unsubscribeMethod.Invoke(hub, new Object[] { this });
}
GC.SuppressFinalize(this);
}
}
}