public InMemoryCommandBus(InMemoryCommandBusConfiguration?configuration = null, IScopeFactory?scopeFactory = null) { if (scopeFactory != null) { _scope = scopeFactory.CreateScope(); } _logger = _scope?.Resolve <ILoggerFactory>()?.CreateLogger <InMemoryCommandBus>() ?? new LoggerFactory(new[] { new DebugLoggerProvider() }).CreateLogger <InMemoryCommandBus>(); _config = configuration ?? InMemoryCommandBusConfiguration.Default; }
internal InMemoryCommandBus(InMemoryCommandBusConfiguration configuration = null, IScopeFactory scopeFactory = null) { if (scopeFactory != null) { _scope = scopeFactory.CreateScope(); } _logger = _scope?.Resolve <ILoggerFactory>()?.CreateLogger <InMemoryCommandBus>() ?? new LoggerFactory().CreateLogger <InMemoryCommandBus>(); _config = configuration ?? InMemoryCommandBusConfiguration.Default; }
/// <summary> /// Dispatch command and context to all handlers. /// </summary> /// <param name="command">Command to dispatch.</param> /// <param name="context">Context associated to command</param> public async Task <Result> DispatchAsync(ICommand command, ICommandContext context = null) { var commandTypeName = command.GetType().FullName; _logger.LogInformation($"InMemoryCommandBus : Beginning of dispatching a command of type {commandTypeName}"); var commandTasks = new List <Task <Result> >(); _config = _config ?? InMemoryCommandBusConfiguration.Default; var ifClause = _config.IfClauses.FirstOrDefault(i => i.Key == command.GetType()).Value; if (ifClause?.Invoke(command) == false) { _logger.LogInformation($"InMemoryCommandBus : If condition for command type {commandTypeName} has returned false."); return(Result.Ok()); } var handlers = TryGetHandlerFromIoCContainer(command); if (!handlers.Any()) { _logger.LogInformation($"InMemoryCommandBus : Handler for command type {commandTypeName} not found in Ioc container, trying to get it from CoreDispatcher."); handlers = TryGetHandlersInstancesFromCoreDispatcher(command); } if (!handlers.Any()) { _logger.LogInformation($"InMemoryCommandBus : Handler for command type {commandTypeName} not found in CoreDispatcher, trying to instantiate if by reflection."); handlers = TryGetHandlersInstancesByReflection(command); } if (!handlers.Any()) { _logger.LogWarning($"InMemoryCommandBus : No handlers for command type {commandTypeName} were found."); _config.OnNoHandlerFounds?.Invoke(command, context); return(Result.Fail($"No handlers for command type {commandTypeName} were found.")); } bool manyHandlersAndShouldWait = false; if (handlers.Skip(1).Any()) { if (!_config.CommandAllowMultipleHandlers.Any(t => new TypeEqualityComparer().Equals(t.CommandType, command.GetType()))) { return(Result.Fail($"the command of type {commandTypeName} have multiple handlers within the same process. " + "If this is expected, you should update your configuration to allow multiple handlers for this specific command type, altough this is not recommended.")); } else { manyHandlersAndShouldWait = _config.CommandAllowMultipleHandlers.FirstOrDefault(t => new TypeEqualityComparer().Equals(t.CommandType, command.GetType()))?.ShouldWait ?? false; } } var cmdHandlers = handlers.ToList(); if (cmdHandlers.Count > 1) { cmdHandlers = cmdHandlers.OrderByDescending(h => h.GetType().GetCustomAttribute <HandlerPriorityAttribute>()?.Priority ?? 0).ToList(); } foreach (var handler in cmdHandlers) { _logger.LogInformation($"InMemoryCommandBus : Invocation of handler of type {handlers.GetType().FullName}"); var handlerType = handler.GetType(); var method = handlerType.GetMethods() .First(m => m.Name == nameof(ICommandHandler <ICommand> .HandleAsync)); try { if (manyHandlersAndShouldWait) { var result = await((Task <Result>)method.Invoke(handler, new object[] { command, context })).ConfigureAwait(false); commandTasks.Add(Task.FromResult(result)); } else { var t = (Task <Result>)method.Invoke(handler, new object[] { command, context }); commandTasks.Add(t); } } catch (Exception e) { _logger.LogErrorMultilines($"InMemoryCommandBus.DispatchAsync() : Exception when trying to dispatch command {commandTypeName} to handler {handler.GetType().FullName}", e.ToString()); if (handlerType.IsDefined(typeof(CriticalHandlerAttribute))) { Result r = Result.Fail($"Critical handler {handlerType.FullName} has failed, so next ones will not be called"); commandTasks.Add(Task.FromResult(r)); break; } } } if (!manyHandlersAndShouldWait) { await Task.WhenAll(commandTasks).ConfigureAwait(false); } if (commandTasks.Count == 1) { return(commandTasks[0].Result); } return(Result.Ok().Combine(commandTasks.Select(t => t.Result).ToArray())); }