/// <summary> /// Create a delegate from an asynchronous (non-cancellable) action. /// </summary> /// <typeparam name="TAttributed">Type of object that contains methods marked with [EventHandler].</typeparam> /// <typeparam name="TEvent">Type of event that is handled by the EventHandlerDelegate.</typeparam> /// <param name="attributedObjectFactory">Factory delegate which produces an instance of <typeparamref name="TAttributed"/>.</param> /// <returns>Instance of EventHandlerDelegate.</returns> private EventHandlerDelegate createNonCancellableAsyncDelegate <TAttributed, TEvent>(Func <TAttributed> attributedObjectFactory) where TAttributed : class where TEvent : class, IEvent { Func <TAttributed, TEvent, Task> asyncAction = (Func <TAttributed, TEvent, Task>)MethodInfo.CreateDelegate(typeof(Func <TAttributed, TEvent, Task>)); return(EventHandlerDelegateBuilder.FromDelegate(attributedObjectFactory, asyncAction)); }
/// <summary> /// Create a delegate from a synchronous action. /// </summary> /// <typeparam name="TAttributed">Type of object that contains methods marked with [EventHandler].</typeparam> /// <typeparam name="TEvent">Type of event that is handled by the EventHandlerDelegate.</typeparam> /// <param name="attributedObjectFactory">Factory delegate which produces an instance of <typeparamref name="TAttributed"/>.</param> /// <returns>Instance of EventHandlerDelegate.</returns> private EventHandlerDelegate createWrappedSyncDelegate <TAttributed, TEvent>(Func <TAttributed> attributedObjectFactory) where TAttributed : class where TEvent : class, IEvent { Action <TAttributed, TEvent> action = (Action <TAttributed, TEvent>)MethodInfo.CreateDelegate(typeof(Action <TAttributed, TEvent>)); return(EventHandlerDelegateBuilder.FromDelegate(attributedObjectFactory, action)); }
/// <summary> /// Register event handler as subscriber. /// </summary> /// <typeparam name="TEvent">Type of event to subscribe to.</typeparam> /// <param name="eventHandlerFactory">Factory which will create an instance of an event handler that handles the specified <typeparamref name="TEvent"/> event.</param> public void Register <TEvent>(Func <IEventHandler <TEvent> > eventHandlerFactory) where TEvent : class, IEvent { if (eventHandlerFactory == null) { throw new ArgumentNullException(nameof(eventHandlerFactory)); } EventHandlerDelegate newSubscribedEventHandlerDelegate = EventHandlerDelegateBuilder.FromFactory(eventHandlerFactory); _eventHandlerDelegateStore.Add(typeof(TEvent), newSubscribedEventHandlerDelegate); }
/// <summary> /// Build message handler delegate that will invoke all async + sync message handlers that were resolved from the container. /// </summary> /// <returns>Message handler delegate that invokes all async + sync message handlers that were resolved from the container.</returns> private MessageHandlerDelegate buildEventHandlerDelegate <TEvent>() where TEvent : class { var handlerDelegates = new List <MessageHandlerDelegate>(); try { // Get all async handlers for the event. IEnumerable <IEventAsyncHandler <TEvent> > resolvedHandlers = _containerAdapter.ResolveMultiple <IEventAsyncHandler <TEvent> >(); if (resolvedHandlers != null) { handlerDelegates.Add(EventHandlerDelegateBuilder.FromEventHandlers(resolvedHandlers)); } } catch (Exception ex) { // Some containers may throw exception when no instance is resolved. // This is to let clients have a way to be notified of the exception. _exceptionHandler?.Invoke(ex); } try { // Get all sync handlers for the event. IEnumerable <IEventHandler <TEvent> > syncEventHandlers = _containerAdapter.ResolveMultiple <IEventHandler <TEvent> >(); if (syncEventHandlers != null) { handlerDelegates.Add(EventHandlerDelegateBuilder.FromEventHandlers(syncEventHandlers, yieldExecution: _yieldExecutionOfSyncHandlers)); } } catch (Exception ex) { // Some containers may throw exception when no instance is resolved. // This is to let clients have a way to be notified of the exception. _exceptionHandler?.Invoke(ex); } // Instantiate a MessageHandlerDelegate. return((message, cancellationToken) => { // Task list. Task[] handleTasks = new Task[handlerDelegates.Count]; // Invoke each message handler delegates to start the tasks and add to task list. for (int i = 0; i < handlerDelegates.Count; i++) { handleTasks[i] = handlerDelegates[i].Invoke(message, cancellationToken); } // Wait for all tasks to complete. return Task.WhenAll(handleTasks); }); }
private IEnumerable <EventHandlerDelegate> buildEventHandlerDelegates <TEvent>() where TEvent : class, IEvent { List <EventHandlerDelegate> handlerDelegates = new List <EventHandlerDelegate>(); try { // Get all async handlers for the event. IEnumerable <IEventAsyncHandler <TEvent> > asyncEventHandlers = _containerAdapter.ResolveMultiple <IEventAsyncHandler <TEvent> >(); if (asyncEventHandlers != null) { // Convert to EventHandlerDelegate. handlerDelegates.AddRange(asyncEventHandlers.Select(eventHandler => { return(EventHandlerDelegateBuilder.FromEventHandler(eventHandler)); })); } } catch (Exception ex) { // Some containers may throw exception when no instance is resolved. _exceptionHandler?.Invoke(ex); } try { // Get all sync handlers for the event. IEnumerable <IEventHandler <TEvent> > syncEventHandlers = _containerAdapter.ResolveMultiple <IEventHandler <TEvent> >(); if (syncEventHandlers != null) { // Convert to EventHandlerDelegate. handlerDelegates.AddRange(syncEventHandlers.Select(eventHandler => { return(EventHandlerDelegateBuilder.FromEventHandler(eventHandler)); })); } } catch (Exception ex) { // Some containers may throw exception when no instance is resolved. _exceptionHandler?.Invoke(ex); } return(new ReadOnlyCollection <EventHandlerDelegate>(handlerDelegates)); }
/// <summary> /// Register event async handler as subscriber. /// </summary> /// <typeparam name="TEvent">Type of event to subscribe to.</typeparam> /// <param name="registration">Instance of MultiMessageHandlerRegistration.</param> /// <param name="eventAsyncHandlerFactory">Factory which will create an instance of an event handler that handles the specified <typeparamref name="TEvent"/> event.</param> public static void RegisterEventHandler <TEvent>(this MultiMessageHandlerRegistration registration, Func <IEventAsyncHandler <TEvent> > eventAsyncHandlerFactory) where TEvent : class { if (registration == null) { throw new ArgumentNullException(nameof(registration)); } if (eventAsyncHandlerFactory == null) { throw new ArgumentNullException(nameof(eventAsyncHandlerFactory)); } MessageHandlerDelegate messageHandlerDelegate = EventHandlerDelegateBuilder.FromEventHandlerFactory(eventAsyncHandlerFactory); registration.Register <TEvent>(messageHandlerDelegate.Invoke); }