/// <summary> /// 保存日志 /// </summary> /// <typeparam name="TCommand">命令类型</typeparam> /// <param name="element">执行元素</param> /// <param name="command">命令</param> /// <param name="ex">异常信息</param> protected void OnCommandHandlerError <TCommand>(CommandExcutingElement element, TCommand command, Exception ex) where TCommand : ICommand { if (element.LoggerAttribute == null) { return; } try { element.LoggerAttribute.OnError(element.CommandContext, element.LoggerBuilder, element.CommandHandler, ex, element.CommandContext); } catch { } finally { } }
/// <summary> /// 发布命令,命令只允许一个消费者,如果存在多个,则会有异常 /// </summary> /// <typeparam name="TCommand">信息类型</typeparam> /// <param name="element">命令元素</param> /// <param name="command">信息</param> /// <param name="communication">上下文通讯</param> /// <param name="handlerResult">处理结果</param> protected IAggregateRoot[] HanderCommand <TCommand>(CommandExcutingElement element, TCommand command, HandlerCommunication communication, ref ICommandHandlerResult handlerResult) where TCommand : ICommand { if (element.CommandHandler == null) { return new IAggregateRoot[] { } } ; if (element.AuthorizeFilters != null) { foreach (var filter in element.AuthorizeFilters) { if (!filter.Validate(element.CommandContext, command)) { return new IAggregateRoot[] { } } ; } } if (element.LoggerBuilder == null) { handlerResult = this.MarkCommandHandlerInvoke(command, element, communication); foreach (var t in element.CommandContext.Items) { communication[t.Key] = t.Value; } } else { element.CommandContext.Items["LoggerBuilder"] = element.LoggerBuilder; try { handlerResult = this.MarkCommandHandlerInvoke(command, element, communication); foreach (var t in element.CommandContext.Items) { communication[t.Key] = t.Value; } } catch (ParameterException ex) { this.OnCommandHandlerError(element, command, ex); throw new ParameterException(ex.ParameterName, "处理出错,请稍后重试", ex); } catch (InvalidException ex) { this.OnCommandHandlerError(element, command, ex); throw new InvalidException("处理出错,请稍后重试", ex); } catch (DomainException ex) { this.OnCommandHandlerError(element, command, ex); throw new DomainException("处理出错,请稍后重试", ex); } catch (StreamStorageException ex) { this.OnCommandHandlerError(element, command, ex); throw new StreamStorageException(ex.Message, ex); } catch (RepositoryExcutingException ex) { this.OnCommandHandlerError(element, command, ex); throw new RepositoryExcutingException(ex.Message, ex); } catch (RepeatExcutingException ex) { this.OnCommandHandlerError(element, command, ex); throw new RepeatExcutingException(ex.Message, ex); } catch (ResourcePoorException ex) { throw new ResourcePoorException(ex.Message, ex); } catch (Exception ex) { this.OnCommandHandlerError(element, command, ex); throw new Exception(ex.Message, ex); } } /*处理聚合根事件*/ var roots = element.CommandContext.GetChangeAggregateRoot(); if (roots == null || roots.Length <= 0) { return new IAggregateRoot[] { } } ; var list = new List <IAggregateRoot>(roots.Length); foreach (var root in roots) { if (root.CanCommit()) { list.Add(root); } } return(list.ToArray()); }
/// <summary> /// 生成方法 /// </summary> /// <typeparam name="TCommand">信息类型</typeparam> /// <param name="command">信息</param> /// <param name="element">命令执行元素</param> /// <param name="communication"></param> /// <returns></returns> protected ICommandHandlerResult MarkCommandHandlerInvoke <TCommand>(TCommand command, CommandExcutingElement element, HandlerCommunication communication) where TCommand : ICommand { try { foreach (var handler in element.HandlerFilters) { handler.OnActionExecuting(element.CommandContext, command); } foreach (var handler in element.ExcuteFilters) { handler.OnActionExecuting(element.CommandContext, command); } /*处理事件*/ return(((ICommandHandler <TCommand>)element.CommandHandler).Execute(element.CommandContext, command)); } catch { throw; } finally { Release(communication); } }
/// <summary> /// 找出当前的命令信息 /// </summary> /// <typeparam name="TCommand">信息类型</typeparam> /// <param name="provider"></param> /// <param name="command">信息</param> /// <param name="communication">上下文通讯</param> /// <returns></returns> internal static CommandExcutingElement FindCommandExcutingElement <TCommand>(CommandHandlerProvider provider, TCommand command, HandlerCommunication communication) where TCommand : ICommand { /*查找事件监听者*/ var commandListeners = provider.FindCommandHandler <TCommand>(); if (commandListeners == null || commandListeners.Length <= 0) { return(new CommandExcutingElement()); } if (commandListeners.Length >= 2) { throw new InvalidException(string.Format("the command {0} has more handler", typeof(TCommand).Name)); } var helper = new CommandExcutingElement(); /*命令上下文*/ var commandContext = provider.FindCommandContext(); var defaultContext = commandContext as ICommandContextInitable; if (defaultContext != null) { defaultContext.OnInit(communication, command); } helper.CommandContext = commandContext; /*发布命令*/ var handler = commandListeners[0]; var handlerType = handler.GetType(); helper.CommandHandler = commandListeners[0]; helper.CommandHandlerType = handler.GetType(); /*handler所有属性*/ var handlerAttributes = HandlerBehaviorStorager.Default.GetAttributes(handlerType); var excuteAttributes = HandlerBehaviorStorager.Default.GetAttributes(handlerType, command.GetType()); var handlerFilters = ObjectExtension.GetAttributes <CommandHandlerFilterAttribute>(handlerAttributes) ?? new CommandHandlerFilterAttribute[] { }; var excuteFilters = ObjectExtension.GetAttributes <CommandHandlerFilterAttribute>(excuteAttributes) ?? new CommandHandlerFilterAttribute[] { }; helper.HandlerFilters = handlerFilters; helper.ExcuteFilters = excuteFilters; /*全局命令过滤器*/ var authorizeAttributes = ObjectExtension.GetAttributes <CommandHandlerAuthorizeAttribute>(handlerAttributes) ?? new CommandHandlerAuthorizeAttribute[] { }; helper.AuthorizeFilters = authorizeAttributes; /*日志预留接口*/ var loggerAttribute = ObjectExtension.GetAttribute <LoggerAttribute>(handlerAttributes); if (loggerAttribute != null) { helper.LoggerAttribute = loggerAttribute; try { var loggerBuilder = loggerAttribute.RegisterKey.IsNotNullOrEmpty() ? provider.Scope.Resolve <ILoggerBuilder>(loggerAttribute.RegisterKey) : provider.Scope.ResolveOptional <ILoggerBuilder>(); helper.LoggerBuilder = loggerBuilder ?? LoggerBuilder.Empty; } catch { } } return(helper); }