### Create Rebus bus starter with `Configure.With` Source: https://github.com/rebus-org/rebus/wiki/Startup-shutdown When using `Configure.With`, instead of calling `Start()` directly, call `Create()` to get an `IBusStarter`. This allows for actions before the bus is fully started. ```csharp var starter = Configure.With(new SomeKindOfContainerAdapter(container)) .(...) .Create(); ``` -------------------------------- ### Initialize Rebus Standalone Source: https://github.com/rebus-org/rebus/wiki/Home Example of initializing and starting Rebus without using a service provider. Replace placeholders with your specific transport and configuration. ```csharp Configure.With(<1>) .Transport(t => t.Use<2>) .<3> .Start(); ``` -------------------------------- ### Fluent Configuration Example with Username Flow Source: https://github.com/rebus-org/rebus/wiki/Auto-flowing-user-context-extensibility-example Example of how to use the EnableUsernameFlow extension method in a fluent Rebus configuration. ```csharp Configure.With(activator) .Transport(t => t.UseMsmq("username-flow-test")) .Options(o => o.EnableUsernameFlow()) .Start(); ``` -------------------------------- ### Configure and Start Rebus with MSMQ Source: https://github.com/rebus-org/rebus/wiki/Getting-started Basic Rebus configuration using MSMQ transport. Ensure MSMQ is installed and the input queue is specified. ```csharp // we have the container adapter in a variable here, but you should stash it // in a static field somewhere, and then dispose it when your app shuts down using var activator = new BuiltinHandlerActivator(); Configure.With(activator) .Transport(t => t.UseMsmq("inputqueue")) .Start(); Console.WriteLine("Press enter to quit"); Console.ReadLine(); ``` -------------------------------- ### Basic Rebus Bus Initialization and Start Source: https://github.com/rebus-org/rebus/blob/master/README.md Demonstrates the fundamental way to instantiate and start the Rebus bus manually. Ensure to dispose of the bus when the application exits. ```csharp var bus = new RebusBus(...); bus.Start(1); // 1 worker thread // use the bus for the duration of the application lifetime // remember to dispose the bus when your application exits bus.Dispose(); ``` -------------------------------- ### Unit of Work Configuration Example Source: https://github.com/rebus-org/rebus/wiki/Unit-of-work An example demonstrating how to configure Rebus with Unit of Work, using Castle Windsor for DI and MSMQ transport. It specifies actions for creation, commit, and cleanup. ```csharp Configure.With(new CastleWindsorContainerAdapter(container)) .Transport(t => t.UseMsmq("uow.test")) .Options(o => { o.EnableUnitOfWork(Create, commitAction: Commit, cleanupAction: Dispose); }) .Start(); ``` -------------------------------- ### Install Rebus and MSMQ Packages Source: https://github.com/rebus-org/rebus/wiki/Getting-started Use NuGet to install the necessary Rebus and MSMQ transport packages for your project. ```powershell Install-Package Rebus -ProjectName Install-Package Rebus.Msmq -ProjectName ``` -------------------------------- ### Delay Rebus bus startup with `Create()` and `Start()` Source: https://github.com/rebus-org/rebus/wiki/Startup-shutdown This pattern is useful when IoC container registrations need to occur after Rebus configuration but before the bus starts processing messages. It ensures all handlers are registered before the bus becomes active. ```csharp var starter = Configure.With(new SomeKindOfContainerAdapter(container)) .(...) .Create(); // fictional registration extensions container.RegisterRebusHandler(); container.RegisterRebusHandler(); container.RegisterRebusHandler(); // now start the bus starter.Start(); ``` -------------------------------- ### Example Handler for CustomerMoved Event Source: https://github.com/rebus-org/rebus/wiki/Handler-pipeline An example of a handler that implements IHandleMessages for a specific event type. ```csharp public class UpdateCustomerInformation : IHandleMessages { ... } ``` -------------------------------- ### Perform actions before starting Rebus bus Source: https://github.com/rebus-org/rebus/wiki/Startup-shutdown Use the `IBusStarter` to access the bus and perform operations like subscribing to events before calling `Start()` to initiate message processing. ```csharp var bus = starter.Bus; // this is a fully functional bus that has not yet been started Task.WaitAll( bus.Subscribe(), bus.Subscribe(), bus.Subscribe() ); // now start the bus starter.Start(); ``` -------------------------------- ### Start RebusBus Source: https://github.com/rebus-org/rebus/wiki/Manual-configuration Start the configured RebusBus instance to begin message processing. This is a necessary step after instantiation and configuration. ```csharp bus.Start(); ``` -------------------------------- ### Example Handler for GeneralCustomerChange Event Source: https://github.com/rebus-org/rebus/wiki/Handler-pipeline An example of a handler that implements IHandleMessages for a base event type, demonstrating polymorphic dispatch. ```csharp public class NotifyCustomerDepartmentSometimes : IHandleMessages { ... } ``` -------------------------------- ### Rebus Extension Logging Setup Source: https://github.com/rebus-org/rebus/wiki/Logging Demonstrates how to retrieve the `IRebusLoggerFactory` from the `IResolutionContext` within a Rebus extension to obtain a logger. ```csharp public static class MsmqTransportConfigurationExtensions { public static void UseMsmq(this StandardConfigurer configurer, string inputQueueName) { configurer.Register(c => { var rebusLoggerFactory = c.Get(); return new MsmqTransport(inputQueueName, rebusLoggerFactory); }); } } ``` -------------------------------- ### Install Rebus Package Source: https://github.com/rebus-org/rebus/wiki/Home Use this command to install the core Rebus package into your .NET project. ```powershell Install-Package Rebus -ProjectName ``` -------------------------------- ### Install Rebus Service Provider Integration Source: https://github.com/rebus-org/rebus/wiki/Home Install this package to easily integrate Rebus with Microsoft's generic host and service provider. ```powershell Install-Package Rebus.ServiceProvider -ProjectName ``` -------------------------------- ### Initialize Rebus with Service Provider Source: https://github.com/rebus-org/rebus/wiki/Home Example of initializing Rebus using the service provider configuration API. Replace placeholders with your specific transport and configuration. ```csharp services.AddRebus( configure => configure .Transport(t => t.Use<2>) .<3> ); ``` -------------------------------- ### Example CustomerMoved Event Class Source: https://github.com/rebus-org/rebus/wiki/Handler-pipeline A sample event class that inherits from a more general change event. ```csharp public class CustomerMoved : GeneralCustomerChange { ... } ``` -------------------------------- ### Configuring Rebus with Serilog and MSMQ Transport Source: https://github.com/rebus-org/rebus/blob/master/README.md Provides a complete example of configuring Rebus with Serilog for logging and MSMQ for transport. It also demonstrates type-based routing. ```csharp Configure.With(someContainerAdapter) .Logging(l => l.Serilog()) .Transport(t => t.UseMsmq("myInputQueue")) .Routing(r => r.TypeBased().MapAssemblyOf("anotherInputQueue")) .Start(); // have IBus injected in application services for the duration of the application lifetime // let the container dispose the bus when your application exits myFavoriteIocContainer.Dispose(); ``` -------------------------------- ### Using the Built-in Handler Activator Source: https://github.com/rebus-org/rebus/wiki/Container-adapters Demonstrates how to initialize and start Rebus with the built-in handler activator and publish messages in a loop. Ensure the activator is disposed when the application shuts down. ```csharp using(var activator = new BuiltinHandlerActivator()) { Configure.With(activator) .Transport(t => t.UseMsmq("inputQueue")) .Start(); // here's the bus var bus = activator.Bus; // publish greetings forever while(true) { bus.Publish(Console.ReadLine()).Wait(); } } ``` -------------------------------- ### Full In-Memory Bus Setup for Testing Source: https://github.com/rebus-org/rebus/wiki/Unit-testing Configure multiple Rebus endpoints that communicate using the in-memory transport for testing message flows. Ensure a shared 'Network' instance is passed to all endpoints. ```csharp var network = new InMemNetwork(); var containerAdapter1 = GetContainerAdapter1(); var containerAdapter2 = GetContainerAdapter2(); using (var bus1 = CreateBus("b1", network, containerAdapter1)) using (var bus2 = CreateBus("b2", network, containerAdapter2)) { // do stuff in here } ``` ```csharp IBus CreateBus(string inputQueueName, InMemNetwork network, IContaineAdapter containerAdapter) { return Configure.With(containerAdapter) .Transport(t => t.UseInMemoryTransport(network, inputQueueName)) .Start(); } ``` -------------------------------- ### Basic In-Memory Bus Configuration for Integration Tests Source: https://github.com/rebus-org/rebus/wiki/How-to-create-integration-tests Configure a Rebus bus with in-memory transport, subscriptions, sagas, and timeouts for integration testing. This setup avoids external dependencies. ```csharp using Rebus.Bus; using Rebus.Config; using Rebus.Tests.Contracts.Utilities; using NUnit.Framework; [Test] public void MyTest() { using var activator = new BuiltinHandlerActivator(); using var bus = Configure.With(activator) .Transport(t => t.UseInMemoryTransport(new InMemNetwork(), "queue-name")) .Subscriptions(s => s.StoreInMemory()) .Sagas(s => s.StoreInMemory()) .Timeouts(t => t.StoreInMemory()) .Start(); // exercise bus here } ``` -------------------------------- ### Conditional Transport and Subscription Configuration Source: https://github.com/rebus-org/rebus/wiki/How-to-create-integration-tests Demonstrates a configuration pattern that allows switching between in-memory test implementations and production-ready transports/stores based on a 'Backdoor' class. This is useful for integrating test-specific configurations into a shared setup. ```csharp Configure.With(activator) .Transport(t => { if (Backdoor.Network != null) { t.UseInMemoryTransport(Backdoor.Network, "queue-name"); } else { t.UseMsmq("queue-name"); } }) .Subscriptions(s => { if (Backdoor.SubscriberStore != null) { s.StoreInMemory(Backdoor.SubscriberStore); } else { s.StoreInSqlServer(connectionString, "Subscriptions", isCentralized: true); } }) .Start(); ``` -------------------------------- ### Example Composite Event Source: https://github.com/rebus-org/rebus/wiki/Polymorphic-message-dispatch Defines a composite event that implements multiple interfaces, demonstrating a scenario for polymorphic dispatch. ```csharp public class SomeCompositeEvent : ISomethingHappened, ISomethingElseHappened { ... } ``` -------------------------------- ### Test sending an email with FakeBus Source: https://github.com/rebus-org/rebus/wiki/How-to-test-code-that-uses-the-bus-to-do-things This example demonstrates testing a service that sends emails via IBus. It uses FakeItEasy for mocking dependencies and FakeBus to verify the sent email. ```csharp public interface IInvitationService { Task Invite(string emailAddress, DateTimeOffset invitationTime); Task ResendInvite(string emailAddress); } ``` ```csharp class DefaultInvitationService : IInvitationService { readonly IEmailTemplateService _emailTemplateService; readonly IBus _bus; public DefaultInvitationService(IBus bus, IEmailTemplateService emailTemplateService) { _bus = bus; _emailTemplateService = emailTemplateService; } public async Task Invite(string emailAddress, DateTimeOffset invitationTime) { var (subject, body) = _emailTemplateService .GetInvitationTemplate( emailAddress: emailAddress, invitationTime: invitationTime ); await _bus.Send(new SendEmail( to: emailAddress, subject: subject, body: body )); } public async Task ResendInvite(string emailAddress) { // ignore for now } } ``` ```csharp [Test] public async Task SendsEmailAsExpected() { // arrange var fakeBus = new FakeBus(); var emailTemplateService = A.Fake(); var sut = new DefaultInvitationService(fakeBus, emailTemplateService); var now = DateTimeOffset.Now; A.CallTo(() => emailTemplateService.GetInvitationTemplate("hello@rebus.fm", now)) .Returns((subject: "interesting subject", body: "great body")); // act await sut.Invite("hello@rebus.fm", now); // assert var sentEmailCommand = fakeBus.Events .OfType>() .Single() .CommandMessage; Assert.That(sentEmailCommand.To, Is.EqualTo("hello@rebus.fm")); Assert.That(sentEmailCommand.Subject, Is.EqualTo("interesting subject")); Assert.That(sentEmailCommand.Body, Is.EqualTo("great body")); } ``` -------------------------------- ### DOS: Rebus Send Pipeline Log Output Source: https://github.com/rebus-org/rebus/wiki/How-to-test-incoming-and-outgoing-steps Example output from Rebus's send pipeline logging, showing the order and details of steps executed, including custom steps like `SetUsernameOutgoingStep` and built-in steps like `AssignDefaultHeadersStep`. ```dos ------------------------------------------------------------------------------ Message pipelines ------------------------------------------------------------------------------ Send pipeline: RebusWikiCodeSamples.SetUsernameOutgoingStep Sets the 'x-upn' header on outgoing messages to the current user's UPN. Rebus.Pipeline.Send.AssignDefaultHeadersStep Assigns these default headers to the outgoing message: 1) a new GUID as the 'rbs2-msg-id' header (*). 2) a 'rbs2-return-address' (unless the bus is a one-way client) (*). 3) a 'rbs2-senttime' with the current time. 4) 'rbs2-msg-type' with the message's simple assembly-qualified type name (*). (*) Unless explicitly set to something else Rebus.Pipeline.Send.FlowCorrelationIdStep Sets the 'rbs2-corr-id' header of the outgoing message to one of the following three things: 1) The correlation ID of the message currently being handled. 2) The message ID of the message currently being handled. 3) The message's own message ID. Rebus.Pipeline.Send.AutoHeadersOutgoingStep If the outgoing message type has [HeaderAttribute(..., ...) on it, the found headers will automatically be picked up and added to the outgoing message. Headers already on the message will not be overwritten. Rebus.Pipeline.Send.SerializeOutgoingMessageStep Serializes the outgoing message using the configured serializer, storing the resulting transport message back to the context. Rebus.Pipeline.Send.ValidateOutgoingMessageStep ``` -------------------------------- ### Install Pipeline Steps using PipelineStepInjector Source: https://github.com/rebus-org/rebus/wiki/Auto-flowing-user-context-extensibility-example Configure Rebus to use the custom pipeline steps by decorating IPipeline with PipelineStepInjector. Positions steps relative to existing ones. ```csharp public static class UsernameFlowConfigurationExtensions { public static void EnableUsernameFlow(this OptionsConfigurer configurer) { configurer.Decorate(c => { var outgoingStep = new SetUsernameOutgoingStep(); var incomingStep = new SetCurrentPrincipalIncomingStep(); var pipeline = c.Get(); return new PipelineStepInjector(pipeline) .OnReceive(incomingStep, PipelineRelativePosition.After, typeof (DeserializeIncomingMessageStep)) .OnSend(outgoingStep, PipelineRelativePosition.Before, typeof (SerializeOutgoingMessageStep)); }); } } ``` -------------------------------- ### Define a Message Handler Source: https://github.com/rebus-org/rebus/wiki/Getting-started Implement the IHandleMessages interface to process incoming messages. This example handles DateTime messages. ```csharp public class PrintDateTime : IHandleMessages { public async Task Handle(DateTime currentDateTime) { Console.WriteLine("The time is {0}", currentDateTime); } } ``` -------------------------------- ### Implement Custom Fail Fast Checker Logic Source: https://github.com/rebus-org/rebus/wiki/Fail-fast-on-certain-exception-types Implement the IFailFastChecker interface to define custom fail-fast conditions. This example shows how to fail fast on a DomainException or a specific SqlException, while delegating other exceptions to the default checker. ```csharp class MyFailFastChecker : IFailFastChecker { readonly IFailFastChecker _failFastChecker; public MyFailFastChecker(IFailFastChecker failFastChecker) { _failFastChecker = failFastChecker; } public bool ShouldFailFast(string messageId, Exception exception) { switch (exception) { // fail fast on our domain exception case DomainException _: return true; // fail fast if table doesn't exist, or we don't have permission case SqlException sqlException when sqlException.Number == 3701: return true; // delegate all other behavior to default default: return _failFastChecker.ShouldFailFast(messageId, exception); } } } ``` -------------------------------- ### Implement Custom Error Handling with Second-Level Retries Source: https://github.com/rebus-org/rebus/wiki/Automatic-retries-and-error-handling Handle failed messages by implementing IHandleMessages>. This example defers the message for 30 seconds or dead-letters it after 5 deferrals. ```csharp public class SomeHandler : IHandleMessages, IHandleMessages> { readonly IBus _bus; public SomeHandler(IBus bus) { _bus = bus; } public async Task Handle(DoStuff message) { // do stuff that can fail here... } public async Task Handle(IFailed failedMessage) { const int maxDeferCount = 5; var deferCount = Convert.ToInt32(message.Headers.GetValueOrDefault(Headers.DeferCount)); if (deferCount >= maxDeferCount) { await _bus.Advanced.TransportMessage.Deadletter($"Failed after {deferCount} deferrals\n\n{message.ErrorDescription}"); return; } await _bus.Advanced.TransportMessage.Defer(TimeSpan.FromSeconds(30)); } } ``` -------------------------------- ### Configure Rebus with `onCreated` callback Source: https://github.com/rebus-org/rebus/wiki/Startup-shutdown Provide an `onCreated` callback to perform actions after the bus is created but before it starts receiving messages. This is useful for subscribing to events. ```csharp services.AddRebus( configure => configure .Transport(...), onCreated: async bus => { await Task.WhenAll( bus.Subscribe(), bus.Subscribe(), bus.Subscribe() ); } ); ``` -------------------------------- ### Use Protobuf Serializer in Rebus Configuration Source: https://github.com/rebus-org/rebus/wiki/Serialization Configure Rebus to use the Protobuf serializer by adding the Rebus.Protobuf package and calling the UseProtobuf() extension method during setup. ```csharp services.AddRebus( configure => configure .(...) .Serialization(s => s.UseProtobuf()) ); ``` -------------------------------- ### Basic Rebus Configuration with IoC Container Source: https://github.com/rebus-org/rebus/wiki/Configuration-API Illustrates the general pattern for configuring Rebus using an IoC container adapter. Ensure the IoC container adapter is correctly implemented and registered. ```csharp Configure.With(myContainerAdapter) .SomeAspect(s => s.ChooseSomeSetting()) .Start(); ``` -------------------------------- ### Pretty-Printed Serialized Message (JSON) Source: https://github.com/rebus-org/rebus/wiki/Messages An example of the serialized JSON message with indentation for better readability. ```json { "\$type": "InventoryManagement.Messages.Events.InventoryItemMoved, InventoryManagement.Messages", "ItemId": "item-234-abc", "NewLocationId": "LOC87484-A" } ``` -------------------------------- ### Basic Saga Unit Test with SagaFixture Source: https://github.com/rebus-org/rebus/wiki/How-to-unit-test-a-saga-handler Demonstrates the basic usage of `SagaFixture` for unit testing a saga. It shows how to create a fixture for a saga, deliver a message, and inspect the saga data after handling. ```csharp using Rebus.TestHelpers.Sagas; using NUnit.Framework; public class YourSaga : Saga { protected override void ConfigureHowToFindSaga(SagaConventionConfigurer config) { config.CorrelateBy(data => data.SomeField, message => ((SomeMessage)message).SomeField); } public void Handle(SomeMessage message) { Data.SomeOtherField = "cool"; } } public class YourSagaData : SagaData { public string SomeField { get; set; } public string SomeOtherField { get; set; } } public class SomeMessage { public string SomeField { get; set; } } [Test] public void CanDoStuff() { // you create a fixture for your saga using (var fixture = SagaFixture.For(() => new YourSaga())) { // and then you do stuff in here - e.g. deliver a message: fixture.Deliver(new SomeMessage { SomeField = "whatever" }); // or inspect the saga data var data = fixture.Data .OfType() .Single(d => d.SomeField == "whatever"); Assert.That(data.SomeOtherField, Is.EqualTo("cool")); // and more :) } } ``` -------------------------------- ### Configure RabbitMQ Transport Source: https://github.com/rebus-org/rebus/wiki/Transport Configure Rebus to use RabbitMQ transport by including the Rebus.RabbitMQ package. Ensure you have RabbitMQ installed and running. ```csharp Configure.With(...) .Transport(t => t.UseRabbitMq("amqp://localhost", "inputQueueName")) // etc ``` -------------------------------- ### Idempotent Saga Data Definition Source: https://github.com/rebus-org/rebus/wiki/Idempotence Example of how to define saga data for an idempotent saga by deriving from IdempotentSagaData. Add your custom properties to this class. ```csharp public class MySagaData : IdempotentSagaData { //.. add your own stuff here } ``` -------------------------------- ### Initialize Serilog with Log Context Source: https://github.com/rebus-org/rebus/wiki/Correlation-ids Configure Serilog to include contextual information in logs. Ensure '.Enrich.FromLogContext()' is called during logger configuration. ```csharp Log.Logger = new LoggerConfiguration() .Enrich.FromLogContext() // ← .WriteTo.(...) .CreateLogger(); ``` -------------------------------- ### Create and use FakeBus Source: https://github.com/rebus-org/rebus/wiki/How-to-test-code-that-uses-the-bus-to-do-things Instantiate FakeBus to mock IBus interactions. Exercise your System Under Test (SUT) and then inspect the recorded events. ```csharp var bus = new FakeBus(); new SomeKindOfSut(bus).DoStuff(); var events = bus.Events; // IEnumerable of things that happened ``` -------------------------------- ### Idempotent Saga Handler Definition Source: https://github.com/rebus-org/rebus/wiki/Idempotence Example of how to define an idempotent saga handler by deriving from IdempotentSaga. This is the base class for creating idempotent sagas. ```csharp public class MySaga : IdempotentSaga, ... { ... } ``` -------------------------------- ### Enable Message Auditing Configuration Source: https://github.com/rebus-org/rebus/wiki/Message-auditing Configure Rebus to enable message auditing and specify the audit queue. This example assumes MSMQ transport. ```csharp Configure.With(adapter) .Transport(t => t.UseMsmq("server.input")) .(...) .Options(b => b.EnableMessageAuditing("audit@cpvm010")) .(...) ``` -------------------------------- ### Naturally Idempotent Domain Operations Source: https://github.com/rebus-org/rebus/wiki/Idempotence Examples of domain object methods that are inherently idempotent. These operations can be safely retried without causing issues. ```csharp obj.MarkAsDeleted(); ``` ```csharp obj.UpdatePeriod(message.NewPeriod); ``` -------------------------------- ### Full Subscriber Configuration with Event Handling Source: https://github.com/rebus-org/rebus/wiki/RabbitMQ-transport A more complete subscriber configuration that includes setting up a handler for a specific event type (MyEvent). Ensure proper disposal of the handler activator. ```csharp using (var activator = new BuiltInHandlerActivator()) { // add handler for MyEvent activator.Handle(async message => { // handle event in here }); // configure subscriber var subscriber = Configure.With(activator) .Transport(t = t.UseRabbitMq(connectionString, "my-subscriber")) .Start(); await subscriber.Subscribe(); Console.WriteLine("Press ENTER to quit") Console.ReadLine(); } ``` -------------------------------- ### Rebus Transport Logging Implementation Source: https://github.com/rebus-org/rebus/wiki/Logging Shows how a Rebus transport can use the `IRebusLoggerFactory` to get a logger for its own class, enabling custom logging within the transport. ```csharp readonly ILog _log; public MsmqTransport(string inputQueueAddress, IRebusLoggerFactory rebusLoggerFactory) { _log = rebusLoggerFactory.GetCurrentClassLogger(); // other stuff down here (...) } ``` -------------------------------- ### Configure Rebus to Use Custom Fail Fast Checker Source: https://github.com/rebus-org/rebus/wiki/Fail-fast-on-certain-exception-types Install a custom fail-fast checker by decorating the IFailFastChecker. This is done within the Rebus configuration options. ```csharp Configure.With(...) .(...) .Options(o => o.UseMyFailFastChecker()) .Start(); ``` -------------------------------- ### Initialize SagaFixture with a factory function Source: https://github.com/rebus-org/rebus/wiki/Unit-testing If your saga handler requires constructor arguments, use SagaFixture.For(() => new MySaga(someDependency)) to provide a factory function that creates an instance of your saga handler. ```csharp using(var fixture = SagaFixture.For(() => new MySaga(someDependency))) { // perform test in here } ``` -------------------------------- ### Configure In-Memory Exception Information Source: https://github.com/rebus-org/rebus/wiki/Automatic-retries-and-error-handling Use this directive at bus creation to enable the `InMemExceptionInfoFactory`, which provides access to raw exceptions. ```cs Configure.With(activator) .Errors(e => e.UseInMemExceptionInfos()) ``` -------------------------------- ### Configure One-Way Client with External Timeout Manager Source: https://github.com/rebus-org/rebus/wiki/Different-bus-modes Sets up a one-way client bus to use an external timeout manager for deferred messages. ```csharp Configure.With(activator) .Transport(t => t.UseMsmqAsOneWayClient()) .Timeouts(o => o.UseExternalTimeoutManager("timeouts")) .(...) ``` -------------------------------- ### Configure Rebus Console Logging Source: https://github.com/rebus-org/rebus/wiki/Logging Set up plain console output logging for Rebus. This is a basic logging configuration. ```csharp Configure.With(...) .Logging(l => l.Console()) // etc ``` -------------------------------- ### Enable SQL Server Outbox Source: https://github.com/rebus-org/rebus/wiki/Outbox Configure Rebus to use the SQL Server outbox by specifying the connection string and table name. Rebus will automatically create the necessary table on startup. ```csharp services.AddRebus( configure => configure .Transport(..) .Outbox(o => o.StoreInSqlServer(connectionString, "Outbox")) ); ``` -------------------------------- ### Rebus Configuration with Built-in Handler Activator Source: https://github.com/rebus-org/rebus/blob/master/README.md Shows how to set up Rebus using the configuration API with the built-in handler activator. This approach integrates with your IoC container for message handler resolution. ```csharp var someContainerAdapter = new BuiltinHandlerActivator(); ``` -------------------------------- ### Instantiate RebusBus Source: https://github.com/rebus-org/rebus/wiki/Manual-configuration Instantiate the RebusBus with necessary components for manual configuration. The constructor requires specific implementations for various functionalities. ```csharp var bus = new RebusBus(...); ``` -------------------------------- ### Integration Test with Hypothesist for Async Assertions Source: https://github.com/rebus-org/rebus/wiki/How-to-create-integration-tests Uses the Hypothesist assertion framework with its Rebus adapter to test asynchronous message handling. This example asserts that a specific string message is eventually received. ```csharp using Rebus.Tests.Contracts.Utilities; using Hypothesist; using System; using System.Threading.Tasks; [Test] public async Task SubscriberGetsPublishedStrings() { // Arrange var hypothesis = Hypothesis.For() .Any(x => x == "HEJ MED DIG MIN VEN"); // hypothesist for async assertions using var activator = new BuiltinHandlerActivator() .Register(hypothesis.AsHandler); // adapater to register the hypothesis as handler // remaining setup equals previous example, except for the manual reset event. await hypothesis.Validate(TimeSpan.FromSeconds(5)); } ``` -------------------------------- ### Rebus Configuration with Custom IoC Container Adapter Source: https://github.com/rebus-org/rebus/blob/master/README.md Illustrates integrating Rebus with a custom IoC container by providing an adapter. The resulting IBus instance is registered as a singleton in the container. ```csharp var someContainerAdapter = new AdapterForMyFavoriteIocContainer(myFavoriteIocContainer); ``` -------------------------------- ### Configure RabbitMQ Publisher and Subscriber Source: https://github.com/rebus-org/rebus/wiki/RabbitMQ-transport Configure two Rebus instances to use RabbitMQ for communication. One acts as a publisher, the other as a subscriber. ```csharp var subscriber = Configure.With(...) .Transport(t = t.UseRabbitMq(connectionString, "my-subscriber")) .Start(); var publisher = Configure.With(...) .Transport(t = t.UseRabbitMq(connectionString, "my-publisher")) .Start(); ``` -------------------------------- ### Register Custom Exception Info Factory Source: https://github.com/rebus-org/rebus/wiki/Automatic-retries-and-error-handling Implement your own `IExceptionInfoFactory` for customized exception handling and register it at bus creation time. ```cs Configure.With(activator) .Errors(e => e.OtherService() .Register(ctx => new FancyExceptionInfoFactory())) ``` -------------------------------- ### Example of Fail Fast Logging with IFailFastException Source: https://github.com/rebus-org/rebus/wiki/Fail-fast-on-certain-exception-types This console output shows the reduced logging when an exception implementing `IFailFastException` is thrown. The '(FINAL)' marker indicates that Rebus has decided to stop retrying and move the message to the error queue immediately. ```console [WRN] Rebus.Retry.ErrorTracking.InMemErrorTracker (Rebus 2 worker 1): Unhandled exception 1 (FINAL) while handling message with ID "819d7779-43e3-4ec7-a2ca-1e6aed82fbf5" MyDomain.DomainException: ( ... full exception details here ... ) [ERR] Rebus.Retry.PoisonQueues.PoisonQueueErrorHandler (Rebus 2 worker 1): Moving message with ID "819d7779-43e3-4ec7-a2ca-1e6aed82fbf5" to error queue "error" System.AggregateException: 1 unhandled exceptions ---> MyDomain.DomainException: ( ... full exception details here ... ) ---> (Inner Exception #0) MyDomain.DomainException: ( ... full exception details here ... ) ``` -------------------------------- ### Subscribe to Events with RabbitMQ Source: https://github.com/rebus-org/rebus/wiki/RabbitMQ-transport After configuring the subscriber, use this to subscribe to all events published by the publisher. ```csharp await subscriber.Subscribe(); ``` -------------------------------- ### Create Data Bus Attachment from Stream Source: https://github.com/rebus-org/rebus/wiki/Data-bus Create a data bus attachment by streaming data from a source. The attachment serves as a claim check, holding only an ID. ```csharp using (var source = File.OpenRead(@"raw-audio.wav")) { var attachment = await bus.Advanced.DataBus.CreateAttachment(source); await bus.Send(new ProcessRecording(attachment)); } ``` -------------------------------- ### Example of Rebus Default Retry Logging Source: https://github.com/rebus-org/rebus/wiki/Fail-fast-on-certain-exception-types This console output demonstrates the default behavior of Rebus when a message handler throws an exception repeatedly. Each retry attempt logs a warning, and the final error log includes an AggregateException containing all previous exceptions. ```console [WRN] Rebus.Retry.ErrorTracking.InMemErrorTracker (Rebus 4 worker 1): Unhandled exception 1 while handling message with ID "488e48bd-20cc-482f-a213-ff8aee3edb82" MyDomain.DomainException: ( ... full exception details here ... ) [WRN] Rebus.Retry.ErrorTracking.InMemErrorTracker (Rebus 4 worker 1): Unhandled exception 2 while handling message with ID "488e48bd-20cc-482f-a213-ff8aee3edb82" MyDomain.DomainException: ( ... full exception details here ... ) [WRN] Rebus.Retry.ErrorTracking.InMemErrorTracker (Rebus 4 worker 1): Unhandled exception 3 while handling message with ID "488e48bd-20cc-482f-a213-ff8aee3edb82" MyDomain.DomainException: ( ... full exception details here ... ) [WRN] Rebus.Retry.ErrorTracking.InMemErrorTracker (Rebus 4 worker 1): Unhandled exception 4 while handling message with ID "488e48bd-20cc-482f-a213-ff8aee3edb82" MyDomain.DomainException: ( ... full exception details here ... ) [WRN] Rebus.Retry.ErrorTracking.InMemErrorTracker (Rebus 4 worker 1): Unhandled exception 5 while handling message with ID "488e48bd-20cc-482f-a213-ff8aee3edb82" MyDomain.DomainException: ( ... full exception details here ... ) [ERR] Rebus.Retry.PoisonQueues.PoisonQueueErrorHandler (Rebus 4 worker 1): Moving message with ID "488e48bd-20cc-482f-a213-ff8aee3edb82" to error queue "error" System.AggregateException: 5 unhandled exceptions ---> ( ... full base exception details here ... ) ---> (Inner Exception #0) MyDomain.DomainException: ( ... full exception details here ... ) ---> (Inner Exception #1) MyDomain.DomainException: ( ... full exception details here ... ) ---> (Inner Exception #2) MyDomain.DomainException: ( ... full exception details here ... ) ---> (Inner Exception #3) MyDomain.DomainException: ( ... full exception details here ... ) ---> (Inner Exception #4) MyDomain.DomainException: ( ... full exception details here ... ) ``` -------------------------------- ### Configure Rebus Trace Logging Source: https://github.com/rebus-org/rebus/wiki/Logging Set up logging for Rebus using System.Diagnostics.Trace. This integrates Rebus logs with the .NET tracing infrastructure. ```csharp Configure.With(...) .Logging(l => l.Trace()) // etc ``` -------------------------------- ### Decorate IPipeline with AutoAccountIdHeader Source: https://github.com/rebus-org/rebus/wiki/Extensibility Extends OptionsConfigurer to decorate the IPipeline, inserting a custom outgoing step that automatically sets the 'x-account-id' header. ```csharp public static void AutomaticallySetAccountIdHeader(this OptionsConfigurer configurer) { configurer.Decorate(c => { var pipeline = c.Get(); var step = new AutoAccountIdOutgoingStep(); return new PipelineStepInjector(pipeline) .OnSend(step, PipelineRelativePosition.Before, typeof(SerializeOutgoingMessageStep)); }); } ``` -------------------------------- ### Incoming Pipeline Step to Set Current Principal Source: https://github.com/rebus-org/rebus/wiki/Auto-flowing-user-context-extensibility-example Implement IIncomingStep to set Thread.CurrentPrincipal based on the 'username' header from incoming messages. Restores the original principal afterwards. ```csharp class SetCurrentPrincipalIncomingStep : IIncomingStep { public async Task Process(IncomingStepContext context, Func next) { var message = context.Load(); var headers = message.Headers; var originalPrincipal = Thread.CurrentPrincipal; try { string username; if (headers.TryGetValue("username", out username)) { Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity(username), new string[0]); } await next(); } finally { Thread.CurrentPrincipal = originalPrincipal; } } } ``` -------------------------------- ### Create Username Flow Configuration Extension Source: https://github.com/rebus-org/rebus/wiki/Auto-flowing-user-context-extensibility-example Extend OptionsConfigurer to provide a fluent API for enabling username flow. This method is called during Rebus configuration. ```csharp public static class UsernameFlowConfigurationExtensions { public static void EnableUsernameFlow(this OptionsConfigurer configurer) { // we'll put some code in here in a second } } ``` -------------------------------- ### Initialize SagaFixture with default constructor Source: https://github.com/rebus-org/rebus/wiki/Unit-testing Use SagaFixture.For() to initialize the fixture when your saga handler has a default constructor. This sets up an in-memory bus and saga storage for testing. ```csharp using(var fixture = SagaFixture.For()) { // perform test in here } ``` -------------------------------- ### Configure Rebus with Serilog Source: https://github.com/rebus-org/rebus/wiki/Logging Integrate Rebus logging with Serilog. This requires the `Rebus.Serilog` package and involves configuring Serilog as usual before enabling it for Rebus. ```csharp // the usual logger stuff here var logger = new LoggerConfiguration() .(...) .CreateLogger(); // might even make it global default Log.Logger = logger; // make Rebus use it too Configure.With(...) .Logging(l => l.Serilog(logger)) // etc ``` -------------------------------- ### Configuring Rebus with Namespace-Based Routing Source: https://github.com/rebus-org/rebus/blob/master/README.md Demonstrates how to configure Rebus routing to map message types within a specific namespace to an input queue. This is useful for organizing message handlers. ```csharp Configure.With(someContainerAdapter) .(...) .Routing(r => r.TypeBased().MapAssemblyNamespaceOf("namespaceInputQueue")) .(...); // have IBus injected in application services for the duration of the application lifetime // let the container dispose the bus when your application exits myFavoriteIocContainer.Dispose(); ``` -------------------------------- ### Subscribe to a Message Type with Rebus Source: https://github.com/rebus-org/rebus/wiki/Introduction Call this at application startup to register interest in receiving specific message types. This configures the bus to deliver matching messages to handlers. ```csharp await bus.Subscribe(); ``` -------------------------------- ### Test saga initiation with InviteNewUserByEmail Source: https://github.com/rebus-org/rebus/wiki/How-to-unit-test-a-saga-handler Tests that receiving an InviteNewUserByEmail message initiates a new saga instance and creates corresponding saga data. Requires a FakeBus and IInvitationService. ```csharp using Rebus.Sagas; using Rebus.Tests.Contracts.Sagas; using NSubstitute; using NUnit.Framework; public class InviteNewUserSagaTests { [Test] public void CanInitiateRegistration() { // arrange var bus = new FakeBus(); var invitationService = NSubstitute.Substitute.For(); using (var fixture = SagaFixture.For(() => new InviteNewUserSaga(bus, invitationService, MessageContext.Current))) { // act fixture.Deliver(new InviteNewUserByEmail("hello@rebus.fm")); // assert var data = fixture.Data .OfType() .FirstOrDefault(d => d.EmailAddress == "hello@rebus.fm"); Assert.That(data, Is.Not.Null); Assert.That(data.EmailAddress, Is.EqualTo("hello@rebus.fm")); } } } ``` -------------------------------- ### C#: Integration Test for Outgoing Step Source: https://github.com/rebus-org/rebus/wiki/How-to-test-incoming-and-outgoing-steps An integration test using NUnit to verify that the custom `SetUsernameOutgoingStep` correctly adds the UPN header. It configures a one-way client with the custom step, sends a message, and asserts the presence and value of the 'x-upn' header using an in-memory network. ```csharp using System; using System.Security.Claims; using System.Threading.Tasks; using NUnit.Framework; using Rebus.Bus; using Rebus.Config; using Rebus.Logging; using Rebus.Messages; using Rebus.Pipeline; using Rebus.Transport.InMem; [Test] public async Task VerifyUpnHeaderIsSet() { // this is the UPN var upn = Guid.NewGuid().ToString(); // establish identity with UPN claim var claimsIdentity = new ClaimsIdentity(new[] { new Claim(ClaimTypes.Upn, upn), }); ClaimsPrincipal.ClaimsPrincipalSelector = () => new ClaimsPrincipal(claimsIdentity); // create one-way client using (var activator = new BuiltinHandlerActivator()) { var network = new InMemNetwork(); var bus = Configure.With(activator) .Transport(t => t.UseInMemoryTransportAsOneWayClient(network)) .Options(o => o.Decorate(c => { var pipeline = c.Get(); var step = new SetUsernameOutgoingStep(); return new PipelineStepInjector(pipeline) .OnSend(step, PipelineRelativePosition.Before, typeof(AssignDefaultHeadersStep)); })) .Options(o => o.LogPipeline(verbose: true)) .Start(); // create destination queue network.CreateQueue("dst-queue"); // send string message to destination queue await bus.Advanced.Routing.Send("dst-queue", "hej med dig"); // retrieve message that was sent var message = network.GetNextOrNull("dst-queue"); Assert.That(message, Is.Not.Null, "Expected to receive a message"); Assert.That(message.Headers, Contains.Key("x-upn").And.ContainValue(upn)); } } ``` -------------------------------- ### Configure Rebus with Microsoft Generic Host Source: https://github.com/rebus-org/rebus/wiki/Container-adapters Use Rebus.ServiceProvider for automatic integration with Microsoft's generic hosting model. This ensures Rebus starts/stops correctly and resolves handlers from the service provider. ```csharp services.AddRebus( configure => configure .Transport(t => t.Use(...)) ); ``` -------------------------------- ### Publish a Message in C# Source: https://github.com/rebus-org/rebus/wiki/Messages Use the 'Publish' method to broadcast a message to subscribers. ```csharp await bus.Publish(new InventoryItemMoved(someItemId, someNewLocationId)); ``` -------------------------------- ### Register Custom IBackoffStrategy Source: https://github.com/rebus-org/rebus/wiki/Back-off-strategy Replace the default back-off strategy by registering your own implementation of `IBackoffStrategy`. This provides full control over the back-off behavior. ```csharp Configure.With(...) .(...) .Options(o => { o.Register(c => { var strategy = new MyOwnBackoffStrategy(); return strategy; }); }) .Start(); ``` -------------------------------- ### Specify Order of Multiple Handlers in Pipeline Source: https://github.com/rebus-org/rebus/wiki/Handler-pipeline Define a specific sequence for multiple handlers that should be executed in order at the beginning of the pipeline. Handlers not specified will be executed after this ordered group. ```csharp Configure.With(...) .Option(o => { .SpecifyOrderOfHandlers() .First() .Then() .Then(); }) //etc ``` -------------------------------- ### Configure Type-Based Routing Source: https://github.com/rebus-org/rebus/wiki/Routing Enable type-based routing in Rebus configuration. ```csharp services.AddRebus( configure => configure .(...) .Routing(r => r.TypeBased()) .(...) ); ``` -------------------------------- ### Configure Centralized SQL Server Subscription Storage Source: https://github.com/rebus-org/rebus/wiki/Pub-sub-messaging Configures Rebus to use SQL Server as a centralized subscription storage. This enables pub/sub behavior even with transports that do not natively support it, by allowing all subscribers and publishers to access a common database. ```csharp Configure.With(...) .(...) .Subscriptions(s => s.StoreInSqlServer(..., isCentralized: true)) .Start(); ``` -------------------------------- ### Configure SQL Server Subscription Storage Source: https://github.com/rebus-org/rebus/wiki/Pub-sub-messaging Configures Rebus to use SQL Server as the subscription storage. This is necessary for transports that do not natively support pub/sub. ```csharp Configure.With(...) .(...) .Subscriptions(s => s.StoreInSqlServer(...)) .Start(); ``` -------------------------------- ### Register Custom Back-off Strategy via Extension Method Source: https://github.com/rebus-org/rebus/wiki/Back-off-strategy A cleaner way to register a custom back-off strategy using an extension method for improved readability. ```csharp Configure.With(...) .(...) .Options(o => o.UseMyOwnBackoffStrategy()) .Start(); ``` -------------------------------- ### Configure Rebus with a Container Adapter Source: https://github.com/rebus-org/rebus/wiki/Container-adapters Integrate Rebus with an IoC container using a container adapter. This delegates handler instantiation to the container and registers the IBus instance with a singleton lifestyle. ```csharp Configure.With(new CastleWindsorContainerAdapter(container)) .(...) ``` -------------------------------- ### Outgoing Pipeline Step to Set Username Header Source: https://github.com/rebus-org/rebus/wiki/Auto-flowing-user-context-extensibility-example Implement IOutgoingStep to add the current thread's principal's name as a 'username' header to outgoing messages if it exists. ```csharp class SetUsernameOutgoingStep : IOutgoingStep { public async Task Process(OutgoingStepContext context, Func next) { var currrentUsername = Thread.CurrentPrincipal?.Identity?.Name; if (currrentUsername != null) { var message = context.Load(); var headers = message.Headers; headers["username"] = currrentUsername; } await next(); } } ``` -------------------------------- ### Integration Test for String Publishing and Subscription Source: https://github.com/rebus-org/rebus/wiki/How-to-create-integration-tests Tests a publish/subscribe scenario where a publisher sends a string message and a subscriber receives it. Uses in-memory transport and subscription storage. A ManualResetEvent is used to wait for the message. ```csharp using Rebus.Bus; using Rebus.Config; using Rebus.Tests.Contracts.Utilities; using NUnit.Framework; using System; using System.Threading; using System.Threading.Tasks; [Test] public async Task SubscriberGetsPublishedStrings() { var network = new InMemNetwork(); var subscriberStore = new InMemorySubscriberStore(); using var publisherActivator = new BuiltinHandlerActivator(); using var subscriberActivator = new BuiltinHandlerActivator(); using var eventWasReceived = new ManualResetEvent(initialState: false); using var publisher = Configure.With(publisherActivator) // rebus v7+: Configure.OneWayClient() .Transport(t => t.UseInMemoryTransport(network, "publisher")) .Subscriptions(s => s.StoreInMemory(subscriberStore)) .Start(); subscriberActivator.Handle(async message => eventWasReceived.Set()); var subscriber = Configure.With(subscriberActivator) .Transport(t => t.UseInMemoryTransport(network, "subscriber")) .Subscriptions(s => s.StoreInMemory(subscriberStore)) .Start(); await subscriber.Subscribe(); await publisher.Publish("HEJ MED DIG MIN VEN"); Assert.That(eventWasReceived.WaitOne(TimeSpan.FromSeconds(5)), Is.True, "Did not receive the published event within 5 s timeout"); } ```