/// <summary> /// This method creates the command handler. You can override this method to set additional properties. /// </summary> /// <param name="holder">The command holder</param> /// <returns>Returns the handler.</returns> protected virtual H CommandHandlerCreate(CommandHolder holder) { var handler = new H(); handler.Initialise(holder); return(handler); }
/// <summary> /// This method will notify the command container when a commands is added or removed. /// </summary> /// <param name="key">The key.</param> /// <param name="remove">Set this to true to remove the command mapping, false is default.</param> protected virtual void CommandNotify(CommandHolder key, bool remove = false, bool isQuorum = false) { try { OnCommandChange?.Invoke(this, new CommandChange(remove, key.Message, isQuorum)); } catch (Exception ex) { Logger?.LogException($"Command {GetType().Name} Change Notification failed", ex); } }
/// <summary> /// This method scans through the command and registers commands that are defined using the metadata tags. /// </summary> protected virtual void CommandsRegisterReflection() { foreach (var signature in this.CommandMethodAttributeSignatures(true)) { var handler = new CommandHolder(CommandChannelAdjust(signature.Item1) , (rq, rs) => signature.Item2.Action(rq, rs, PayloadSerializer) , referenceId: signature.Item3); CommandRegister(handler); } }
/// <summary> /// This method is used to register a command holder for a particular method. /// </summary> /// <param name="cHolder">The holder.</param> protected void CommandRegister(CommandHolder cHolder) { mSupported.Add(cHolder, CommandHandlerCreate(cHolder)); switch (mPolicy.CommandNotify) { case CommandNotificationBehaviour.OnRegistration: CommandNotify(cHolder, false); break; case CommandNotificationBehaviour.OnRegistrationIfStarted: if (Status == ServiceStatus.Running) { CommandNotify(cHolder, false); } break; } }
/// <summary> /// This method registers a particular command. /// </summary> /// <param name="channelId">The message channelId</param> /// <param name="messageType">The command channelId</param> /// <param name="actionType">The command action</param> /// <param name="command">The action delegate to execute.</param> protected void CommandRegister(MessageFilterWrapper key, Func <TransmissionPayload, List <TransmissionPayload>, Task> action, Func <TransmissionPayload, List <TransmissionPayload>, Task> deadLetterAction = null, Func <Exception, TransmissionPayload, List <TransmissionPayload>, Task> exceptionAction = null) { if (key == null) { throw new ArgumentNullException("CommandRegister: key cannot be null"); } Func <TransmissionPayload, List <TransmissionPayload>, Task> command = async(rq, rs) => { bool error = false; Exception actionEx = null; try { //Depending on the message type, execute the deadletter action. if (rq.IsDeadLetterMessage && deadLetterAction != null) { await deadLetterAction(rq, rs); } else { await action(rq, rs); } } catch (Exception ex) { if (exceptionAction == null) { throw; } error = true; actionEx = ex; } try { if (error) { await exceptionAction(actionEx, rq, rs); } } catch (Exception ex) { throw; } }; if (key.Header.IsPartialKey && key.Header.ChannelId == null) { throw new Exception("You must supply a channel when using a partial key."); } var cHolder = new CommandHolder(key); mSupported.Add(cHolder, CommandHandlerCreate(key, command)); switch (mPolicy.CommandNotify) { case CommandNotificationBehaviour.OnRegistration: CommandNotify(cHolder, false); break; case CommandNotificationBehaviour.OnRegistrationIfStarted: if (Status == ServiceStatus.Running) { CommandNotify(cHolder, false); } break; } }
/// <summary> /// This is the constructor for registering a manual command. /// </summary> /// <param name="message">The message filter wrapper route to identify the command.</param> /// <param name="command">The command to process.</param> /// <param name="referenceId">The optional reference id for tracking.</param> public CommandInline(MessageFilterWrapper message , Func <TransmissionPayload, List <TransmissionPayload>, IPayloadSerializationContainer, Task> command , string referenceId = null) : base(null) { mCommandHolder = new CommandHolder(message, async(rq, rs) => await command(rq, rs, PayloadSerializer), referenceId); }
/// <summary> /// This method initialises the holder. /// </summary> /// <param name="parent">The name of the parent container.</param> /// <param name="key"></param> /// <param name="action"></param> public virtual void Initialise(CommandHolder holder) { Key = holder.Message; Action = holder.Command; }