/// <summary> /// Returns a boolean value indicating whether registering the specified query handler is authorized. /// </summary> /// <typeparam name="TQuery">The type of query.</typeparam> /// <param name="queryHandlerFactory">The query handler that shall be registered.</param> /// <returns>True if registering <paramref name="queryHandlerFactory"/> is authorized, false otherwise.</returns> /// <exception cref="ArgumentNullException">Thrown if <paramref name="queryHandlerFactory"/> is null.</exception> public bool IsRegistrationAuthorized <TQuery>(IContextualProvider <IQueryHandler <TQuery> > queryHandlerFactory) { if (queryHandlerFactory == null) { throw new ArgumentNullException(nameof(queryHandlerFactory)); } return(_authorizationVerifyer.AuthorizeHandlerRegistry()); }
/// <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); } }
private Task PushHandler(IContextualProvider <THandler> handlerFactory) { _handlerStack = _handlerStack.Add(handlerFactory); if (handlerFactory is IActivationNotifyable notifyable) { return(notifyable.NotifyActivationAsync()); } return(Task.CompletedTask); }
public IProjectionRegistration <IProjection <TSource, TProjection> > RegisterProjection <TSource, TProjection>( IContextualProvider <IProjection <TSource, TProjection> > projectionProvider) where TSource : class where TProjection : class { if (projectionProvider == null) { throw new ArgumentNullException(nameof(projectionProvider)); } return(_typedProjectors.GetProjector <TSource, TProjection>() .RegisterProjection(projectionProvider)); }
/// <summary> /// Unregisters a handler. /// </summary> /// <param name="provider">The handler to unregister.</param> /// <returns> /// A boolean value indicating whether the handler was actually found and unregistered. /// </returns> /// <exception cref="ArgumentNullException">Thrown if <paramref name="provider"/> is null.</exception> public bool Unregister(IContextualProvider <THandler> handler) { if (handler == null) { throw new ArgumentNullException(nameof(handler)); } Debug.Assert(_handlers != null); ImmutableList <IContextualProvider <THandler> > current = _handlers, // Volatile read op. start, desired; do { start = current; // If no handlers are present, we cannot remove anything. if (start.IsEmpty) { return(false); } // Read the top of stack var tos = start.Last(); // If handlers are present, there has to be a top of stack. Debug.Assert(tos != null); // If the handler to remove is on top of stack, remove the top of stack. if (handler == tos) { desired = start.RemoveAt(start.Count - 1); } else { desired = start.Remove(handler); if (desired == start) { return(false); } } current = Interlocked.CompareExchange(ref _handlers, desired, start); }while (start != current); return(true); }
/// <summary> /// Tries to retrieve the currently activated handler. /// </summary> /// <param name="handlerFactory">Contains the handler if true is returned, otherwise the value is undefined.</param> /// <returns>True if a handler was found, false otherwise.</returns> public bool TryGetHandler(out IContextualProvider <THandler> handlerFactory) { var handlerStack = _handlerStack; Debug.Assert(handlerStack != null); if (handlerStack.IsEmpty) { handlerFactory = null; return(false); } handlerFactory = handlerStack.Last(); return(true); }
/// <summary> /// Tries to retrieve the currently activated handler. /// </summary> /// <param name="handler">Contains the handler if true is returned, otherwise the value is undefined.</param> /// <returns>True if a handler was found, false otherwise.</returns> public bool TryGetHandler(out IContextualProvider <THandler> handler) { var handlers = _handlers; // Volatile read op. Debug.Assert(handlers != null); if (handlers.IsEmpty) { handler = null; return(false); } handler = handlers.Last(); return(true); }
/// <summary> /// Asynchronously registers a message handler. /// </summary> /// <typeparam name="TMessage">The type of message the handler handles.</typeparam> /// <typeparam name="TResponse">The type of response the handler returns.</typeparam> /// <param name="handlerFactory">The message handler to register.</param> /// <returns> /// A <see cref="IHandlerRegistration"/> representing the asynchronous operation. /// The <see cref="IHandlerRegistration"/> cancels the handler registration if completed. /// </returns> /// <exception cref="ArgumentNullException">Thrown if <paramref name="handlerFactory"/> is null.</exception> public async Task <IHandlerRegistration> RegisterAsync <TMessage, TResponse>(IContextualProvider <IMessageHandler <TMessage, TResponse> > handlerFactory) // TODO: Correct xml-comments { if (handlerFactory == null) { throw new ArgumentNullException(nameof(handlerFactory)); } ThrowIfDisposed(); await Initialization; _logger?.LogInformation($"Registering handler for message type '{typeof(TMessage).FullName}' and result type '{typeof(TMessage).FullName}'."); var result = await GetMessageReceiver <TMessage>().RegisterAsync(handlerFactory); _logger?.LogInformation($"Registered handler for message type '{typeof(TMessage).FullName}' and result type '{typeof(TMessage).FullName}'."); return(result); }
public TypedProjectionRegistration(IProjectionRegistry <TProjection> projectionRegistry, IContextualProvider <TProjection> projectionProvider) { if (projectionRegistry == null) { throw new ArgumentNullException(nameof(projectionRegistry)); } if (projectionProvider == null) { throw new ArgumentNullException(nameof(projectionProvider)); } _handlerRegistry = projectionRegistry; Projection = projectionProvider; _handlerRegistry.Register(Projection); }
public HandlerRegistration(IAsyncHandlerRegistry <THandler> handlerRegistry, IContextualProvider <THandler> handlerFactory) { if (handlerRegistry == null) { throw new ArgumentNullException(nameof(handlerRegistry)); } if (handlerFactory == null) { throw new ArgumentNullException(nameof(handlerFactory)); } _handlerRegistry = handlerRegistry; _handlerFactory = handlerFactory; Initialization = _handlerRegistry.RegisterAsync(_handlerFactory); }
/// <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(); } } }
/// <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(_handlers != null); Debug.Assert(_lock != null); using (await _lock.LockAsync()) { if (!_handlers.Contains(handlerFactory)) { return(false); } var handlers = _handlers.Remove(handlerFactory); if (handlers.IsEmpty) { await _dispatchForwarding.UnregisterForwardingAsync(); } if (handlers.IsEmpty && handlerFactory is IDeactivationNotifyable deactivationNotifyable) { await deactivationNotifyable.NotifyDeactivationAsync(); } _handlers = handlers; if (_handlers.Count == 1 && _handlers.First() is IActivationNotifyable activationNotifyable) { await activationNotifyable.NotifyActivationAsync(); } return(true); } }
public async Task <IHandlerRegistration> RegisterAsync <TEvent, TEntity>(IContextualProvider <IEventReplayer <TId, TEventBase, TEntityBase, TEvent, TEntity> > eventReplayerFactory) where TEvent : TEventBase where TEntity : TEntityBase { if (eventReplayerFactory == null) { throw new ArgumentNullException(nameof(eventReplayerFactory)); } IAsyncSingleHandlerRegistry <IEventReplayer <TId, TEventBase, TEntityBase> > handlerRegistry; ImmutableDictionary <Type, ImmutableDictionary <Type, IAsyncSingleHandlerRegistry <IEventReplayer <TId, TEventBase, TEntityBase> > > > current = _replayer, start, desired; do { start = current; if (start.TryGetValue(typeof(TEvent), out var perEventRegistry) && perEventRegistry.TryGetValue(typeof(TEntity), out handlerRegistry)) { break; } desired = start.Remove(typeof(TEvent)); handlerRegistry = new AsyncSingleHandlerRegistry <IEventReplayer <TId, TEventBase, TEntityBase> >(); perEventRegistry = (perEventRegistry ?? ImmutableDictionary <Type, IAsyncSingleHandlerRegistry <IEventReplayer <TId, TEventBase, TEntityBase> > > .Empty) .Add(typeof(TEntity), handlerRegistry); desired = desired.Add(typeof(TEvent), perEventRegistry); current = Interlocked.CompareExchange(ref _replayer, desired, start); }while (current != start); var untypedFactory = new EventReplayerFactory <TEvent, TEntity>(eventReplayerFactory); return(await HandlerRegistration.CreateRegistrationAsync(handlerRegistry, untypedFactory)); }
/// <summary> /// Registers a handler. /// </summary> /// <param name="provider">The handler to register.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="provider"/> is null.</exception> public bool Register(IContextualProvider <THandler> handler) { if (handler == null) { throw new ArgumentNullException(nameof(handler)); } Debug.Assert(_handlers != null); ImmutableList <IContextualProvider <THandler> > current = _handlers, // Volatile read op. start; do { start = current; // We can assume that the to be registered handler (provider) is a single time in the collection at most. // We check if the handler (provider) is the top of stack. If this is true, nothing has to be done. // handler is never null if (start.LastOrDefault() == handler) { return(false); } // If the collection does already contain the handler (provider), we do nothing. if (start.Contains(handler)) { return(false); } current = Interlocked.CompareExchange(ref _handlers, start.Add(handler), start); }while (start != current); return(true); }
/// <summary> /// Asynchronously registers an event handler. /// </summary> /// <typeparam name="TEvent">The type of event.</typeparam> /// <param name="eventHandlerFactory">The event handler to register.</param> /// <returns> /// A <see cref="IHandlerRegistration"/> representing the asynchronous operation. /// The <see cref="IHandlerRegistration"/> cancels the handler registration if completed. /// </returns> /// <exception cref="ArgumentNullException">Thrown if <paramref name="eventHandlerFactory"/> is null.</exception> /// <exception cref="UnauthorizedAccessException">Thrown if the access is unauthorized.</exception> public Task <IHandlerRegistration <IEventHandler <TEvent> > > RegisterAsync <TEvent>(IContextualProvider <IEventHandler <TEvent> > eventHandlerFactory) // TODO: Correct xml-comments { if (eventHandlerFactory == null) { throw new ArgumentNullException(nameof(eventHandlerFactory)); } if (!_authorizationVerifyer.AuthorizeHandlerRegistry()) { throw new UnauthorizedAccessException(); } return(GetTypedDispatcher <TEvent>().RegisterAsync(eventHandlerFactory)); }
public IProjectionRegistration <IProjection <TSource, TProjection> > RegisterProjection(IContextualProvider <IProjection <TSource, TProjection> > projectionProvider) { Assert(projectionProvider != null); return(ProjectionRegistration.CreateRegistration(_projections, projectionProvider)); }
// TODO: Xml-comment public Task <IHandlerRegistration <IQueryHandler <TQuery> > > RegisterAsync <TQuery>(IContextualProvider <IQueryHandler <TQuery> > queryHandlerFactory) { if (queryHandlerFactory == null) { throw new ArgumentNullException(nameof(queryHandlerFactory)); } return(GetTypedDispatcher <TQuery>().RegisterAsync(queryHandlerFactory)); }
/// <summary> /// Asynchronously registers the specified handler in the specified handler registry and returns a handler registration. /// </summary> /// <typeparam name="THandler">The type of handler.</typeparam> /// <param name="handlerRegistry">The handler registry that the handler shall be registered to.</param> /// <param name="handlerProvider">A contextual provider that provides instances of the to be registered handler.</param> /// <returns>A task representing the asynchronous operation.</returns> public static IProjectionRegistration <THandler> CreateRegistration <THandler>( this IProjectionRegistry <THandler> handlerRegistry, IContextualProvider <THandler> handlerProvider) { return(new TypedProjectionRegistration <THandler>(handlerRegistry, handlerProvider)); }