Beispiel #1
0
        /// <summary>
        /// 发布命令,命令只允许一个消费者,如果存在多个,则会有异常
        /// </summary>
        /// <typeparam name="TCommand">信息类型</typeparam>
        /// <param name="command">信息</param>
        /// <param name="communication">上下文通讯</param>
        public override ICommandHandlerResult Send <TCommand>(TCommand command, HandlerCommunication communication)
        {
            var serialCommand = command as ISerialCommand;

            if (serialCommand == null || string.IsNullOrEmpty(serialCommand.Body))
            {
                return(base.Send(command, communication));
            }

            /*获取到权限,则执行任务,在执行完毕后要释放*/
            var row = Database.Use(serialCommand).Select(serialCommand);

            try
            {
                row.WaitOne();
                return(base.Send(command, communication));
            }
            catch
            {
                throw;
            }
            finally
            {
                row.Release();
            }
        }
Beispiel #2
0
        /// <summary>
        /// 发布命令,命令只允许一个消费者,如果存在多个,则会有异常
        /// </summary>
        /// <typeparam name="TCommand">信息类型</typeparam>
        /// <param name="command">信息</param>
        /// <param name="communication">上下文通讯</param>
        public virtual ICommandHandlerResult Send <TCommand>(TCommand command, HandlerCommunication communication) where TCommand : ICommand
        {
            var commandType = command.GetType();

            this.OnCommandValidating(command, commandType);

            if (communication == null)
            {
                communication = new HandlerCommunication();
            }

            var element = this.FindCommandExcutingElement(command, communication);

            try
            {
                /*先保存命令*/
                this.HandlerCommandToStorage(element.CommandContext, command);
                ICommandHandlerResult handlerResult = null;
                var roots = this.HanderCommand(element, command, communication, ref handlerResult);
                if (roots == null || roots.Length == 0)
                {
                    communication.HandlerResult = handlerResult;
                    return(handlerResult);
                }

                if (handlerResult != null && handlerResult.Status != CommandHandlerStatus.Success)
                {
                    communication.HandlerResult = handlerResult;
                    return(handlerResult);
                }

                var eventArray  = new List <KeyValuePair <Type, IEvent[]> >(roots.Length);
                var eventSource = new List <IEvent[]>(roots.Length);
                foreach (var root in roots)
                {
                    var array = root.Change(root.Version + root.GetChangeCounts());
                    eventSource.Add(array);
                    var item = new KeyValuePair <Type, IEvent[]>(root.GetType(), array);
                    eventArray.Add(item);
                }

                /*先保存事件*/
                this.HandlerEventToStorage(element.CommandContext, eventArray);

                /*再发布事件*/
                this.HandlerEventToPublish(element.CommandContext, eventSource);

                communication.HandlerResult = handlerResult;
                return(handlerResult);
            }
            catch
            {
                throw;
            }
            finally
            {
                OnReturningWhenHandlerExecuted(element.CommandContext);
            }
        }
Beispiel #3
0
        /// <summary>
        /// 新加运行时类型到上下文
        /// </summary>
        /// <param name="commandBus">命令总线</param>
        /// <param name="communication">上下文通讯</param>
        /// <param name="runtimeMode">当前运行模式</param>
        public static void AddRuntimeMode(this ICommandBus commandBus, HandlerCommunication communication, Aop.IRuntimeMode runtimeMode)
        {
            if (communication == null || runtimeMode == null)
            {
                return;
            }

            communication.RuntimeModeArray.Add(runtimeMode);
        }
Beispiel #4
0
        /// <summary>
        /// 新加运行时类型到上下文
        /// </summary>
        /// <param name="commandBus">命令总线</param>
        /// <param name="communication">上下文通讯</param>
        /// <param name="runtimeMode">当前运行模式</param>
        public static void AddRuntimeMode(this ICommandBus commandBus, HandlerCommunication communication, string runtimeMode)
        {
            if (communication == null)
            {
                return;
            }

            AddRuntimeMode(commandBus, communication, new Aop.DefaultRuntimeMode()
            {
                RuntimeMode = runtimeMode
            });
        }
Beispiel #5
0
        /// <summary>
        /// 释放由<see cref="IServiceLocator"/>创建的对象
        /// </summary>
        /// <param name="context"></param>
        protected void Release(HandlerCommunication context)
        {
            var scope = context.ContainsKey("BeginLifetimeScope") ? context["BeginLifetimeScope"] as ILifetimeScope : null;

            if (scope != null)
            {
                try
                {
                    scope.Dispose();
                    context.Remove("BeginLifetimeScope");
                }
                catch
                {
                }
            }
        }
Beispiel #6
0
        /// <summary>
        /// 初始化命令
        /// </summary>
        /// <param name="communication">上下文通讯</param>
        /// <param name="command">命令对象</param>
        public virtual void OnInit(HandlerCommunication communication, ICommand command)
        {
            if (communication != null)
            {
                foreach (var item in communication)
                {
                    this.Items[item.Key] = item.Value;
                }
            }

            var principal = System.Threading.Thread.CurrentPrincipal as UserPrincipal;

            if (principal != null)
            {
                if (this.Consigner == null)
                {
                    this.Consigner = principal.CurrentUser;
                }

                if (this.Worker == null)
                {
                    this.Worker = principal.CurrentUser as IWorker;
                }
            }

            if (communication.Consigner != null)
            {
                this.Consigner = communication.Consigner;
            }

            if (communication.Worker != null)
            {
                this.Worker = communication.Worker;
            }

            if (communication.RuntimeModeArray != null)
            {
                if (this.RuntimeModeArray == null)
                {
                    this.RuntimeModeArray = new Aop.IRuntimeMode[communication.RuntimeModeArray.Count];
                }

                communication.RuntimeModeArray.CopyTo(this.RuntimeModeArray, 0);
            }
        }
Beispiel #7
0
        /// <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);
            }
        }
Beispiel #8
0
        /// <summary>
        /// 找出当前的命令信息
        /// </summary>
        /// <typeparam name="TCommand">信息类型</typeparam>
        /// <param name="command">信息</param>
        /// <param name="communication">上下文通讯</param>
        /// <returns></returns>
        protected CommandExcutingElement FindCommandExcutingElement <TCommand>(TCommand command, HandlerCommunication communication) where TCommand : ICommand
        {
            var provider = new CommandHandlerProvider(this.serviceLocator.BeginLifetimeScope());
            var element  = CommandBusExcutingHelper.FindCommandExcutingElement(provider, command, communication);

            communication["BeginLifetimeScope"] = provider.Scope;
            return(element);
        }
Beispiel #9
0
        /// <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());
        }
Beispiel #10
0
 /// <summary>
 /// 异步发布命令,命令只允许一个消费者,如果存在多个,则会有异常
 /// </summary>
 /// <typeparam name="TCommand">信息类型</typeparam>
 /// <param name="c">信息</param>
 /// <param name="communication">上下文通讯</param>
 public async virtual Task <HandlerCommunication> SendAsync <TCommand>(TCommand c, HandlerCommunication communication) where TCommand : ICommand
 {
     return(await Task <HandlerCommunication> .Factory.StartNew(() => { this.Send(c, communication); return communication; }));
 }
Beispiel #11
0
        /// <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);
        }