/// <summary> /// Asynchronously deregisters a handler. /// </summary> /// <param name="handlerFactory">The handler to deregister.</param> /// <returns> /// A task representing the asynchronous operation. /// The value of the <see cref="Task{TResult}.Result"/> parameter contains a boolean value /// indicating whether the handler was actually found and deregistered. /// </returns> /// <exception cref="ArgumentNullException">Thrown if <paramref name="handlerFactory"/> is null.</exception> public async Task <bool> DeregisterAsync(IContextualProvider <THandler> handlerFactory) { if (handlerFactory == null) { throw new ArgumentNullException(nameof(handlerFactory)); } Debug.Assert(_handlerStack != null); Debug.Assert(_lock != null); using (await _lock.LockAsync()) { if (_handlerStack.IsEmpty) { return(false); } var tos = _handlerStack.Last(); Debug.Assert(tos != null); if (handlerFactory.Equals(tos)) { if (handlerFactory is IDeactivationNotifyable deactivationNotifyable) { await deactivationNotifyable.NotifyDeactivationAsync(); } // Handler stack will be empty afterwards if (_handlerStack.Count == 1) { await _dispatchForwarding.UnregisterForwardingAsync(); } else if (_handlerStack[_handlerStack.Count - 2] is IActivationNotifyable activationNotifable) { await activationNotifable.NotifyActivationAsync(); } _handlerStack = _handlerStack.RemoveAt(_handlerStack.Count - 1); return(true); } var newStack = _handlerStack.Remove(handlerFactory); if (newStack == _handlerStack) { return(false); } _handlerStack = newStack; return(true); } }
/// <summary> /// Asynchronously registers a handler. /// </summary> /// <param name="handlerFactory">The handler to register.</param> /// <returns>A task representing the asynchronous operation.</returns> /// <exception cref="ArgumentNullException">Thrown if <paramref name="handlerFactory"/> is null.</exception> public async Task RegisterAsync(IContextualProvider <THandler> handlerFactory) { if (handlerFactory == null) { throw new ArgumentNullException(nameof(handlerFactory)); } Debug.Assert(_handlerStack != null); Debug.Assert(_lock != null); using (await _lock.LockAsync()) { if (_handlerStack.IsEmpty) { await PushHandler(handlerFactory); await _dispatchForwarding.RegisterForwardingAsync(); } else { var tos = _handlerStack.Last(); Debug.Assert(tos != null); if (handlerFactory.Equals(tos)) { await _dispatchForwarding.RegisterForwardingAsync(); return; } if (tos is IDeactivationNotifyable notifyable) { await notifyable.NotifyDeactivationAsync(); } _handlerStack = _handlerStack.Remove(handlerFactory); await PushHandler(handlerFactory); await _dispatchForwarding.RegisterForwardingAsync(); } } }