/// <summary>
        /// This extension adds the inline command to the pipeline
        /// </summary>
        /// <typeparam name="E">The pipeline type.</typeparam>
        /// <param name="cpipe">The pipeline.</param>
        /// <param name="contract">The contract.</param>
        /// <param name="commandFunction">The command function.</param>
        /// <param name="referenceId">The reference identifier.</param>
        /// <param name="startupPriority">The startup priority.</param>
        /// <param name="channelResponse">The channel response.</param>
        /// <returns>Returns the pipeline.</returns>
        /// <exception cref="InvalidMessageContractException"></exception>
        /// <exception cref="InvalidPipelineChannelContractException"></exception>
        public static E AttachCommand <E>(this E cpipe, Type contract
                                          , Func <CommandMethodRequestContext, Task> commandFunction
                                          , string referenceId  = null
                                          , int startupPriority = 100
                                          , IPipelineChannelOutgoing <IPipeline> channelResponse = null
                                          )
            where E : IPipelineChannelIncoming <IPipeline>
        {
            string channelId, messageType, actionType;

            if (!ServiceMessageHelper.ExtractContractInfo(contract, out channelId, out messageType, out actionType))
            {
                throw new InvalidMessageContractException(contract);
            }

            if (channelId != cpipe.Channel.Id)
            {
                throw new InvalidPipelineChannelContractException(contract, channelId, cpipe.Channel.Id);
            }

            var command = new CommandMethodInline((channelId, messageType, actionType), commandFunction, referenceId);

            cpipe.Pipeline.AddCommand(command, startupPriority, null, cpipe, channelResponse);

            return(cpipe);
        }
Beispiel #2
0
        /// <summary>
        /// This method unregisters a command.
        /// </summary>
        /// <typeparam name="C">The message contract type</typeparam>
        protected virtual void CommandUnregister <C>() where C : IMessageContract
        {
            string channelId, messageType, actionType;

            ServiceMessageHelper.ExtractContractInfo <C>(out channelId, out messageType, out actionType);
            CommandUnregister(channelId, messageType, actionType);
        }
        /// <summary>
        /// This method unregisters a command.
        /// </summary>
        /// <typeparam name="C">The message contract type</typeparam>
        protected virtual void CommandUnregister <C>() where C : IMessageContract
        {
            string channelId, messageType, actionType;

            if (!ServiceMessageHelper.ExtractContractInfo <C>(out channelId, out messageType, out actionType))
            {
                throw new InvalidMessageContractException(typeof(C));
            }
            CommandUnregister(channelId, messageType, actionType);
        }
Beispiel #4
0
        /// <summary>
        /// This method register a command.
        /// </summary>
        /// <typeparam name="C">The contract channelId.</typeparam>
        /// <param name="action">The process action.</param>
        /// <param name="exceptionAction">The optional action call if an exception is thrown.</param>
        protected virtual void CommandRegister <CM>(
            Func <TransmissionPayload, List <TransmissionPayload>, Task> action,
            Func <TransmissionPayload, List <TransmissionPayload>, Task> deadLetterAction           = null,
            Func <Exception, TransmissionPayload, List <TransmissionPayload>, Task> exceptionAction = null)
            where CM : IMessageContract
        {
            string channelId, messageType, actionType;

            ServiceMessageHelper.ExtractContractInfo <CM>(out channelId, out messageType, out actionType);

            CommandRegister(channelId, messageType, actionType, action, deadLetterAction, exceptionAction);
        }
Beispiel #5
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="CM"></typeparam>
        /// <param name="action"></param>
        /// <param name="exceptionAction"></param>
        protected virtual void CommandRegister <CM>(
            Func <TransmissionPayload, List <TransmissionPayload>, Task> action,
            Func <Exception, TransmissionPayload, List <TransmissionPayload>, Task> exceptionAction = null)
            where CM : IMessageContract
        {
            string channelId, messageType, actionType;

            if (!ServiceMessageHelper.ExtractContractInfo <CM>(out channelId, out messageType, out actionType))
            {
                throw new InvalidMessageContractException(typeof(CM));
            }

            CommandRegister((channelId, messageType, actionType), action, exceptionAction, typeof(CM).Name);
        }
Beispiel #6
0
        /// <summary>
        /// This method creates a service message and injects it in to the execution path and bypasses the listener infrastructure.
        /// </summary>
        /// <typeparam name="C">The message contract.</typeparam>
        /// <param name="package">The objet package to process.</param>
        /// <param name="ChannelPriority">The prioirty that the message should be processed. The default is 1. If this message is not a valid value, it will be matched to the nearest valid value.</param>
        /// <param name="options">The process options.</param>
        /// <param name="release">The release action which is called when the payload has been executed.</param>
        /// by the receiving commands.</param>
        public void Process <C>(object package                = null
                                , int ChannelPriority         = 1
                                , ProcessOptions options      = ProcessOptions.RouteExternal | ProcessOptions.RouteInternal
                                , Action <bool, Guid> release = null)
            where C : IMessageContract
        {
            string channelId, messageType, actionType;

            if (!ServiceMessageHelper.ExtractContractInfo <C>(out channelId, out messageType, out actionType))
            {
                throw new InvalidMessageContractException(typeof(C));
            }

            Process(channelId, messageType, actionType, package, ChannelPriority, options, release);
        }
        /// <summary>
        /// This method is used to send requests to the remote command.
        /// </summary>
        /// <typeparam name="I">The contract interface.</typeparam>
        /// <typeparam name="RQ">The request type.</typeparam>
        /// <typeparam name="RS">The response type.</typeparam>
        /// <param name="rq">The request object.</param>
        /// <param name="routing"></param>
        /// <param name="settings"></param>
        /// <returns>Returns a response object of the specified type in a response metadata wrapper.</returns>
        protected virtual async Task <ResponseWrapper <RS> > ProcessOutgoing <I, RQ, RS>(RQ rq
                                                                                         , RequestSettings settings = null
                                                                                         , ProcessOptions?routing   = null
                                                                                         , IPrincipal principal     = null)
            where I : IMessageContract
        {
            string channelId, messageType, actionType;

            if (!ServiceMessageHelper.ExtractContractInfo <I>(out channelId, out messageType, out actionType))
            {
                throw new InvalidOperationException("Unable to locate message contract attributes for " + typeof(I));
            }

            return(await ProcessOutgoing <RQ, RS>(channelId, messageType, actionType, rq, settings, routing
                                                  , principal : principal ?? Thread.CurrentPrincipal));
        }
        public CommandContractAttribute(Type interfaceType)
        {
            if (!interfaceType.IsInterface || interfaceType.IsSubclassOf(typeof(IMessageContract)))
            {
                throw new ArgumentOutOfRangeException("interfaceType must be an interface and derived from IMessageContract");
            }

            string channelId, messageType, actionType;

            if (!ServiceMessageHelper.ExtractContractInfo(interfaceType, out channelId, out messageType, out actionType))
            {
                throw new InvalidOperationException($"Unable to locate contract attributes for {interfaceType.Name}");
            }

            Header = new ServiceMessageHeader(channelId, messageType, actionType);
        }
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static TransmissionPayload Create <T>(bool traceEnabled = false) where T : IMessageContract
        {
            string channelId, messageType, actionType;

            if (!ServiceMessageHelper.ExtractContractInfo(typeof(T), out channelId, out messageType, out actionType))
            {
                throw new InvalidOperationException("Unable to locate contract attributes for " + typeof(T));
            }

            var message = new ServiceMessage
            {
                ChannelId   = channelId,
                MessageType = messageType,
                ActionType  = actionType
            };

            return(new TransmissionPayload(message, traceEnabled: traceEnabled));
        }
        /// <summary>
        /// This method is used to send requests to the remote command.
        /// </summary>
        /// <typeparam name="I">The contract interface.</typeparam>
        /// <typeparam name="RQ">The request type.</typeparam>
        /// <typeparam name="RS">The response type.</typeparam>
        /// <param name="rq">The request object.</param>
        /// <param name="rqSettings">The request settings. Use this to specifically set the timeout parameters.</param>
        /// <param name="routingOptions">The routing options by default this will try internal and then external.</param>
        /// <param name="processResponse"></param>
        /// <param name="fallbackMaxProcessingTime">This is the fallback max processing time used if the timeout
        /// is not set in the request settings.
        /// If this is also null, the max time out will fall back to the policy settings.</param>
        /// <param name="principal">This is the principal that you wish the command to be executed under.
        /// By default this is taken from the calling thread if not passed.</param>
        /// <returns>Returns the async response wrapper.</returns>
        /// <returns>Returns a response object of the specified type in a response metadata wrapper.</returns>
        protected internal virtual async Task <ResponseWrapper <RS> > ProcessOutgoing <I, RQ, RS>(RQ rq
                                                                                                  , RequestSettings rqSettings    = null
                                                                                                  , ProcessOptions?routingOptions = null
                                                                                                  , Func <TaskStatus, TransmissionPayload, bool, ResponseWrapper <RS> > processResponse = null
                                                                                                  , TimeSpan?fallbackMaxProcessingTime = null
                                                                                                  , IPrincipal principal = null)
            where I : IMessageContract
        {
            string channelId, messageType, actionType;

            if (!ServiceMessageHelper.ExtractContractInfo <I>(out channelId, out messageType, out actionType))
            {
                throw new InvalidOperationException("Unable to locate message contract attributes for " + typeof(I));
            }

            return(await ProcessOutgoing <RQ, RS>(channelId, messageType, actionType
                                                  , rq
                                                  , rqSettings
                                                  , routingOptions
                                                  , processResponse
                                                  , fallbackMaxProcessingTime
                                                  , principal ?? Thread.CurrentPrincipal
                                                  ));
        }