Пример #1
0
        /// <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());
        }
Пример #2
0
        /// <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);
            }
        }
Пример #3
0
        private Task PushHandler(IContextualProvider <THandler> handlerFactory)
        {
            _handlerStack = _handlerStack.Add(handlerFactory);

            if (handlerFactory is IActivationNotifyable notifyable)
            {
                return(notifyable.NotifyActivationAsync());
            }

            return(Task.CompletedTask);
        }
Пример #4
0
        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));
        }
Пример #5
0
        /// <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);
        }
Пример #6
0
        /// <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);
        }
Пример #7
0
        /// <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);
        }
Пример #8
0
        /// <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);
            }
Пример #10
0
        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);
        }
Пример #11
0
        /// <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();
                }
            }
        }
Пример #12
0
        /// <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);
            }
        }
Пример #13
0
        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));
        }
Пример #14
0
        /// <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);
        }
Пример #15
0
        /// <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));
        }
Пример #16
0
 public IProjectionRegistration <IProjection <TSource, TProjection> > RegisterProjection(IContextualProvider <IProjection <TSource, TProjection> > projectionProvider)
 {
     Assert(projectionProvider != null);
     return(ProjectionRegistration.CreateRegistration(_projections, projectionProvider));
 }
Пример #17
0
        // 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));
 }