/// <summary> /// Registers a step which set and load the message id header from IMessage.MessageId /// </summary> /// <param name="configurer"></param> public static void CatchMessagesSent(this OptionsConfigurer configurer) { var step = new CatchMessagesSentStep(); configurer.Decorate <IPipeline>(c => { var pipeline = c.Get <IPipeline>(); return(new PipelineStepInjector(pipeline) .OnSend(step, PipelineRelativePosition.After, typeof(SendOutgoingMessageStep))); }); }
/// <summary> /// Configures Rebus to execute handlers inside a <see cref="TransactionScope"/>, using the transaction options /// given by <paramref name="transactionOptions"/> for the transaction scope /// </summary> public static void HandleMessagesInsideTransactionScope(this OptionsConfigurer configurer, TransactionOptions transactionOptions) { if (configurer == null) { throw new ArgumentNullException(nameof(configurer)); } configurer.Decorate <IPipeline>(c => { var pipeline = c.Get <IPipeline>(); var stepToInject = new TransactionScopeIncomingStep(transactionOptions); return(new PipelineStepInjector(pipeline) .OnReceive(stepToInject, PipelineRelativePosition.Before, typeof(DispatchIncomingMessageStep))); }); }
public static void IncludePrincipalClaims(this OptionsConfigurer configurer, IServiceProvider provider) { configurer.Decorate <IPipeline>(c => { var pipeline = c.Get <IPipeline>(); var step = provider.GetRequiredService <IncludePrincipalClaimsStep>(); return(new PipelineStepInjector(pipeline) .OnSend(step, PipelineRelativePosition.Before, typeof(AutoHeadersOutgoingStep))); }); configurer.Decorate <IPipeline>(c => { var pipeline = c.Get <IPipeline>(); var step = provider.GetRequiredService <IncludePrincipalClaimsStep>(); return(new PipelineStepInjector(pipeline) .OnReceive(step, PipelineRelativePosition.Before, typeof(DispatchIncomingMessageStep))); }); }
/// <summary> /// Registers a step which set and load the message id header from IMessage.MessageId /// </summary> /// <param name="configurer"></param> public static void AutoSetMessageId(this OptionsConfigurer configurer) { var step = new AutoSetMessageIdStep(); configurer.Decorate <IPipeline>(c => { var pipeline = c.Get <IPipeline>(); return(new PipelineStepInjector(pipeline) .OnSend(step, PipelineRelativePosition.Before, typeof(AssignDefaultHeadersStep))); }); configurer.Decorate <IPipeline>(c => { var pipeline = c.Get <IPipeline>(); return(new PipelineStepInjector(pipeline) .OnReceive(step, PipelineRelativePosition.After, typeof(DeserializeIncomingMessageStep))); }); }
/// <summary> /// Registers a step which the scope of each pipeline /// </summary> /// <param name="configurer"></param> /// <param name="provider"></param> public static void ApplyServiceProvider(this OptionsConfigurer configurer, IServiceProvider provider) { var step = new ServiceProviderStep(provider); configurer.Decorate <IPipeline>(c => { var pipeline = c.Get <IPipeline>(); var retryStep = c.Get <IRetryStrategyStep>(); return(new PipelineStepInjector(pipeline) .OnReceive(step, PipelineRelativePosition.Before, retryStep.GetType())); }); configurer.Decorate <IPipeline>(c => { var pipeline = c.Get <IPipeline>(); return(new PipelineStepInjector(pipeline) .OnSend(step, PipelineRelativePosition.Before, typeof(AssignDefaultHeadersStep))); }); }
/// <summary> /// Registers a custom IErrorHandler which emits events for any exceptions raised by a command /// </summary> /// <param name="configurer"></param> /// <param name="provider"></param> public static void HandleCommandsEvents(this OptionsConfigurer configurer, IServiceProvider provider) { configurer.Register <IErrorHandler>(c => { var simpleRetryStrategySettings = c.Get <SimpleRetryStrategySettings>(); var transport = c.Get <ITransport>(); var serializer = c.Get <ISerializer>(); var rebusLoggerFactory = c.Get <IRebusLoggerFactory>(); return(new CommandsErrorHandler(provider, serializer, simpleRetryStrategySettings, transport, rebusLoggerFactory)); }); configurer.Decorate <IPipeline>(c => { var pipeline = c.Get <IPipeline>(); var step = new CompleteCommandEventStep(c.Get <IErrorTracker>(), provider); return(new PipelineStepInjector(pipeline) .OnReceive(step, PipelineRelativePosition.After, typeof(DispatchIncomingMessageStep))); }); }
/// <summary> /// Enables async/await-based request/reply whereby a request can be sent using the <see cref="AsyncBusExtensions.SendRequest{TReply}"/> method /// which can be awaited for a corresponding reply. /// </summary> public static void EnableSynchronousRequestReply(this OptionsConfigurer configurer) { if (configurer == null) { throw new ArgumentNullException(nameof(configurer)); } configurer.Register(c => { var rebusLoggerFactory = c.Get <IRebusLoggerFactory>(); var step = new ReplyHandlerStep(AsyncBusExtensions.Messages, rebusLoggerFactory); return(step); }); configurer.Decorate <IPipeline>(c => { var pipeline = c.Get <IPipeline>(); var step = c.Get <ReplyHandlerStep>(); return(new PipelineStepInjector(pipeline) .OnReceive(step, PipelineRelativePosition.Before, typeof(ActivateHandlersStep))); }); }
/// <summary> /// Configures Rebus to execute handlers inside a <see cref="TransactionScope"/>, using the transaction options /// given by <paramref name="transactionOptions"/> for the transaction scope. /// <para> /// The <see cref="TransactionScope"/> is managed with an <see cref="ITransport"/> decorator, /// which means that it gets created before receiving the incoming message. /// </para> /// <para> /// <code> /// Configure.With(..)<para/> /// .(...)<para/> /// .Options(o => o.LogPipeline(verbose: true)<para/> /// .Start();<para/> /// </code> /// </para> /// </summary> public static void HandleMessagesInsideTransactionScope(this OptionsConfigurer configurer, TransactionOptions transactionOptions) { if (configurer == null) { throw new ArgumentNullException(nameof(configurer)); } configurer.Decorate <ITransport>(c => { var transport = c.Get <ITransport>(); return(new TransactionScopeTransportDecorator(transport, transactionOptions)); }); configurer.Decorate <IPipeline>(c => { var pipeline = c.Get <IPipeline>(); return(new PipelineStepInjector(pipeline) .OnReceive(new TransactionScopeIncomingStep(), PipelineRelativePosition.After, typeof(DeserializeIncomingMessageStep))); }); }
/// <summary> /// Wraps the invocation of the incoming pipeline in a step that creates a unit of work, committing/rolling back depending on how the invocation of the pipeline went. The cleanup action is always called. /// </summary> public static void EnableUnitOfWork <TUnitOfWork>(this OptionsConfigurer configurer, Func <IMessageContext, TUnitOfWork> create, Action <IMessageContext, TUnitOfWork> commit, Action <IMessageContext, TUnitOfWork> rollback = null, Action <IMessageContext, TUnitOfWork> dispose = null) { if (create == null) { throw new ArgumentNullException(nameof(create), "You need to provide a factory method that is capable of creating new units of work"); } if (commit == null) { throw new ArgumentNullException(nameof(commit), "You need to provide a commit action that commits the current unit of work"); } configurer.EnableAsyncUnitOfWork( create: async context => create(context), commit: async(context, unitOfWork) => commit(context, unitOfWork), rollback: async(context, unitOfWork) => rollback?.Invoke(context, unitOfWork), dispose: async(context, unitOfWork) => dispose?.Invoke(context, unitOfWork) ); }
/// <summary> /// Makes Rebus "legacy compatible", i.e. enables wire-level compatibility with older Rebus versions. WHen this is enabled, /// all endpoints need to be old Rebus endpoints or new Rebus endpoints with this feature enabled /// </summary> public static void EnableLegacyCompatibility(this OptionsConfigurer configurer) { configurer.Register(c => new LegacyFlag()); configurer.Register <ISerializer>(c => { var specialSettings = LegacySubscriptionMessagesBinder.JsonSerializerSettings; var legacyEncoding = Encoding.UTF7; var jsonSerializer = new CustomJsonSerializer(specialSettings, legacyEncoding); return(jsonSerializer); }); configurer.Decorate(c => { var pipeline = c.Get <IPipeline>(); // map headers of incoming message from v1 to v2 pipeline = new PipelineStepConcatenator(pipeline) .OnReceive(new MapLegacyHeadersIncomingStep(), PipelineAbsolutePosition.Front); // unpack object[] of transport message pipeline = new PipelineStepInjector(pipeline) .OnReceive(new UnpackLegacyMessageIncomingStep(), PipelineRelativePosition.After, typeof(DeserializeIncomingMessageStep)); // pack into object[] pipeline = new PipelineStepInjector(pipeline) .OnSend(new PackLegacyMessageOutgoingStep(), PipelineRelativePosition.Before, typeof(SerializeOutgoingMessageStep)); pipeline = new PipelineStepInjector(pipeline) .OnSend(new MapLegacyHeadersOutgoingStep(), PipelineRelativePosition.Before, typeof(SendOutgoingMessageStep)); //pipeline = new PipelineStepInjector(pipeline) // .OnReceive(new HandleLegacySubscriptionRequestIncomingStep(c.Get<ISubscriptionStorage>(), c.Get<LegacySubscriptionMessageSerializer>()), PipelineRelativePosition.Before, typeof(MapLegacyHeadersIncomingStep)); return(pipeline); }); }
/// <summary> /// Wraps the invocation of the incoming pipeline in a step that creates a unit of work, committing/rolling back depending on how the invocation of the pipeline went. The cleanup action is always called. /// </summary> public static void EnableAsyncUnitOfWork <TUnitOfWork>(this OptionsConfigurer configurer, Func <IMessageContext, Task <TUnitOfWork> > create, Func <IMessageContext, TUnitOfWork, Task> commit, Func <IMessageContext, TUnitOfWork, Task> rollback = null, Func <IMessageContext, TUnitOfWork, Task> dispose = null) { if (create == null) { throw new ArgumentNullException(nameof(create), "You need to provide a factory method that is capable of creating new units of work"); } if (commit == null) { throw new ArgumentNullException(nameof(commit), "You need to provide a commit action that commits the current unit of work"); } configurer.Decorate <IPipeline>(context => { var pipeline = context.Get <IPipeline>(); var unitOfWorkStep = new UnitOfWorkStep <TUnitOfWork>(create, commit, rollback, dispose); return(new PipelineStepInjector(pipeline) .OnReceive(unitOfWorkStep, PipelineRelativePosition.Before, typeof(ActivateHandlersStep))); }); }
/// <summary> /// Gets a standard configurer from the given options configurer. Can be used to provide /// extensions to <see cref="OptionsConfigurer"/> that return a standard configurer that can then /// be used to build further /// </summary> public static StandardConfigurer <TService> GetConfigurerFrom(OptionsConfigurer configurer) { return(configurer.GetConfigurer <TService>()); }