/// <summary> /// Sends the specified command. We expect only one handler. The command is handled synchronously. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="command">The command.</param> /// <exception cref="System.ArgumentException"> /// </exception> public void Send <T>(T command) where T : class, IRequest { if (_handlerFactory == null) { throw new InvalidOperationException("No handler factory defined."); } var requestContext = _requestContextFactory.Create(); requestContext.Policies = _policyRegistry; using (var builder = new PipelineBuilder <T>(_subscriberRegistry, _handlerFactory)) { _logger.Value.InfoFormat("Building send pipeline for command: {0} {1}", command.GetType(), command.Id); var handlerChain = builder.Build(requestContext); AssertValidSendPipeline(command, handlerChain.Count()); handlerChain.First().Handle(command); } }
/// <summary> /// Publishes the specified event. We expect zero or more handlers. The events are handled synchronously, in turn /// Because any pipeline might throw, yet we want to execute the remaining handler chains, we catch exceptions on any publisher /// instead of stopping at the first failure and then we throw an AggregateException if any of the handlers failed, /// with the InnerExceptions property containing the failures. /// It is up the implementer of the handler that throws to take steps to make it easy to identify the handler that threw. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="event">The event.</param> public void Publish <T>(T @event) where T : class, IRequest { if (_handlerFactory == null) { throw new InvalidOperationException("No handler factory defined."); } var requestContext = _requestContextFactory.Create(); requestContext.Policies = _policyRegistry; requestContext.FeatureSwitches = _featureSwitchRegistry; using (var builder = new PipelineBuilder <T>(_subscriberRegistry, _handlerFactory, _inboxConfiguration)) { _logger.Value.InfoFormat("Building send pipeline for event: {0} {1}", @event.GetType(), @event.Id); var handlerChain = builder.Build(requestContext); var handlerCount = handlerChain.Count(); _logger.Value.InfoFormat("Found {0} pipelines for event: {1} {2}", handlerCount, @event.GetType(), @event.Id); var exceptions = new List <Exception>(); foreach (var handleRequests in handlerChain) { try { handleRequests.Handle(@event); } catch (Exception e) { exceptions.Add(e); } } if (exceptions.Any()) { throw new AggregateException("Failed to publish to one more handlers successfully, see inner exceptions for details", exceptions); } } }
/// <summary> /// Sends the specified command. We expect only one handler. The command is handled synchronously. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="command">The command.</param> /// <exception cref="System.ArgumentException"> /// </exception> public void Send <T>(T command) where T : class, IRequest { if (_handlerFactorySync == null) { throw new InvalidOperationException("No handler factory defined."); } var requestContext = _requestContextFactory.Create(); requestContext.Policies = _policyRegistry; requestContext.FeatureSwitches = _featureSwitchRegistry; using (var builder = new PipelineBuilder <T>(_subscriberRegistry, _handlerFactorySync, _inboxConfiguration)) { s_logger.LogInformation("Building send pipeline for command: {CommandType} {Id}", command.GetType(), command.Id); var handlerChain = builder.Build(requestContext); AssertValidSendPipeline(command, handlerChain.Count()); handlerChain.First().Handle(command); } }