private async ValueTask ProcessMessageHandlingExceptionAsync(IMessageScope scope, IMessageHandlerFactory asyncHandlerFactory, Type messageType, IMessage message, List <Exception> exceptions) { var asyncEventHandler = asyncHandlerFactory.GetHandler(scope); try { if (asyncEventHandler == null) { throw new ArgumentNullException($"Registered async message handler for message type {messageType.Name} is null!"); } var asyncHandlerType = typeof(IAsyncMessageHandler <>).MakeGenericType(messageType); var method = asyncHandlerType.GetMethod( nameof(IAsyncMessageHandler <IMessage> .HandleMessageAsync), new[] { messageType } ); await(ValueTask) method.Invoke(asyncEventHandler, new object[] { message }); } catch (TargetInvocationException ex) { exceptions.Add(ex.InnerException); } catch (Exception ex) { exceptions.Add(ex); } finally { asyncHandlerFactory.ReleaseHandler(scope, asyncEventHandler); } }
private async ValueTask ProcessRichMessageHandlingExceptionAsync(IMessageScope scope, IMessageHandlerFactory asyncHandlerFactory, Type messageType, IMessage message, IRichMessageDescriptor descriptor, List <Exception> exceptions) { var handlerInstance = asyncHandlerFactory.GetHandler(scope); try { if (handlerInstance == null) { throw new ArgumentNullException($"Registered async rich message handler for message type {messageType.Name} is null!"); } var ifType = typeof(IAsyncRichMessageHandler <>).MakeGenericType(messageType); var method = ifType.GetMethod( nameof(IAsyncRichMessageHandler <IMessage> .HandleMessageAsync), new[] { messageType, typeof(IRichMessageDescriptor) } ); await(ValueTask) method.Invoke(handlerInstance, new object[] { message, descriptor }); } catch (TargetInvocationException ex) { exceptions.Add(ex.InnerException); } catch (Exception ex) { exceptions.Add(ex); } finally { asyncHandlerFactory.ReleaseHandler(scope, handlerInstance); } }
private void ProcessMessageHandlingException(IMessageScope scope, IMessageHandlerFactory handlerFactory, Type messageType, IMessage message, List <Exception> exceptions) { var eventHandler = handlerFactory.GetHandler(scope); try { if (eventHandler == null) { throw new ArgumentNullException($"Registered message handler for message type {messageType.Name} is null!"); } var handlerType = typeof(IMessageHandler <>).MakeGenericType(messageType); var method = handlerType.GetMethod( nameof(IMessageHandler <IMessage> .HandleMessage), new[] { messageType } ); method.Invoke(eventHandler, new object[] { message }); } catch (TargetInvocationException ex) { exceptions.Add(ex.InnerException); } catch (Exception ex) { exceptions.Add(ex); } finally { handlerFactory.ReleaseHandler(scope, eventHandler); } }
public async ValueTask <bool> CallAsync( IMessageScope scope, IMessageHandlerFactory handlerFactory, IMessage message, IRichMessageDescriptor messageDescriptor, List <Exception> exceptions = null, CancellationToken cancellationToken = default) { exceptions = exceptions ?? new List <Exception>(); var handlerDescriptor = handlerFactory.GetHandlerDescriptor(); if (handlerDescriptor.IsAsync) { if (handlerDescriptor.IsRich) { await ProcessRichMessageHandlingExceptionAsync(scope, handlerFactory, handlerDescriptor.MessageType, message, messageDescriptor, exceptions); } else { await ProcessMessageHandlingExceptionAsync(scope, handlerFactory, handlerDescriptor.MessageType, message, exceptions); } } else { if (handlerDescriptor.IsRich) { ProcessRichMessageHandlingException(scope, handlerFactory, handlerDescriptor.MessageType, message, messageDescriptor, exceptions); } else { ProcessMessageHandlingException(scope, handlerFactory, handlerDescriptor.MessageType, message, exceptions); } } return(true); }
public virtual void ReleaseHandler(IMessageScope messageScope, IMessageHandler handler) { if (handler == null) { return; } messageScope.Release(handler); }
public virtual IMessageHandler GetHandler(IMessageScope messageScope) { if (messageScope == null) { return(null); } return(messageScope.Resolve(_descriptor.HandlerType) as IMessageHandler); }
protected async ValueTask ProcessMessageAsync(IMessageScope scope, Type messageType, IMessage message, IRichMessageDescriptor descriptor) { var exceptions = new List <Exception>(); await new SynchronizationContextRemover(); foreach (var handlerFactories in _messageHandlerFactoryStore.GetHandlerFactories(messageType).ToList()) { foreach (var handlerFactory in handlerFactories.MessageHandlerFactories) { var isCallSuccess = await _messageHandlerCaller.CallAsync(scope, handlerFactory, message, descriptor, exceptions); if (!isCallSuccess) { var errorMessage = $"Call message handler error"; exceptions.Add(new MessageBusException(errorMessage)); } } } //Implements generic argument inheritance. See IMessageWithInheritableGenericArgument if (messageType.IsGenericType && messageType.GenericTypeArguments.Length == 1 && typeof(IMessageWithInheritableGenericArgument).IsAssignableFrom(messageType)) { var genericArg = messageType.GetGenericArguments()[0]; var baseArg = genericArg.BaseType; if (baseArg != null) { var baseMessageType = messageType.GetGenericTypeDefinition().MakeGenericType(baseArg); var constructorArgs = ((IMessageWithInheritableGenericArgument)messageType).GetConstructorArgs(); //TODO: Use Expression Tree instead / or do Inheritable Abstractions var baseMessage = (IMessage)Activator.CreateInstance(baseMessageType, constructorArgs); await ProcessMessageAsync(scope, baseMessageType, baseMessage, descriptor); } } if (exceptions.Any()) { if (exceptions.Count == 1) { ExceptionDispatchInfo.Capture(exceptions[0]).Throw(); } throw new AggregateException("More than one error has occurred while handling the message: " + messageType, exceptions); } }
public async ValueTask <bool> CallAsync(IMessageScope scope, IMessageHandlerFactory handlerFactory, IMessage message, IRichMessageDescriptor messageDescriptor, List <Exception> exceptions = null, CancellationToken cancellationToken = default) { var handlerDescriptor = handlerFactory.GetHandlerDescriptor(); IMessageHandler handler = null; try { handler = handlerFactory.GetHandler(scope); if (handlerDescriptor.IsAsync) { await GetOrCreateAsyncHandlerCallCache(handlerDescriptor).Invoke(handler, message, messageDescriptor); } else { GetOrCreateSyncHandlerCallCache(handlerDescriptor).Invoke(handler, message, messageDescriptor); } } catch (TargetInvocationException e) { exceptions?.Add(e.InnerException); return(false); } catch (Exception e) { exceptions?.Add(e); return(false); } finally { if (handler != null) { handlerFactory.ReleaseHandler(scope, handler); } } return(true); }
public void Add(IMessageScope scope) { _messageScopes.Add(scope); }