diff --git a/samples/bridge/simple/Bridge_4/Bridge.sln b/samples/bridge/simple/Bridge_4/Bridge.sln
new file mode 100644
index 00000000000..7c95799815e
--- /dev/null
+++ b/samples/bridge/simple/Bridge_4/Bridge.sln
@@ -0,0 +1,35 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29728.190
+MinimumVisualStudioVersion = 15.0.26730.12
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shared", "Shared\Shared.csproj", "{5686FE6C-A5E3-40D1-A6BD-25F94DA612F8}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LeftSender", "LeftSender\LeftSender.csproj", "{7036A49B-359F-4BC7-AFBA-DE3C7AB41986}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LeftReceiver", "LeftReceiver\LeftReceiver.csproj", "{6A699A4E-F2FD-4B71-AF73-199B499482BD}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RightReceiver", "RightReceiver\RightReceiver.csproj", "{96028F4C-6B27-4CBE-95EB-A39F1EDCE045}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bridge", "Bridge\Bridge.csproj", "{355C998A-AAC0-4BAB-87B3-C5D34DE9C0B1}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {5686FE6C-A5E3-40D1-A6BD-25F94DA612F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5686FE6C-A5E3-40D1-A6BD-25F94DA612F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7036A49B-359F-4BC7-AFBA-DE3C7AB41986}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7036A49B-359F-4BC7-AFBA-DE3C7AB41986}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6A699A4E-F2FD-4B71-AF73-199B499482BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6A699A4E-F2FD-4B71-AF73-199B499482BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {96028F4C-6B27-4CBE-95EB-A39F1EDCE045}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {96028F4C-6B27-4CBE-95EB-A39F1EDCE045}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {355C998A-AAC0-4BAB-87B3-C5D34DE9C0B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {355C998A-AAC0-4BAB-87B3-C5D34DE9C0B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/samples/bridge/simple/Bridge_4/Bridge/Bridge.csproj b/samples/bridge/simple/Bridge_4/Bridge/Bridge.csproj
new file mode 100644
index 00000000000..2110fa9e3b0
--- /dev/null
+++ b/samples/bridge/simple/Bridge_4/Bridge/Bridge.csproj
@@ -0,0 +1,19 @@
+
+
+
+ net10.0
+ Exe
+ preview
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/bridge/simple/Bridge_4/Bridge/Program.cs b/samples/bridge/simple/Bridge_4/Bridge/Program.cs
new file mode 100644
index 00000000000..5332640fc00
--- /dev/null
+++ b/samples/bridge/simple/Bridge_4/Bridge/Program.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using NServiceBus;
+
+static class Program
+{
+ static async Task Main()
+ {
+ Console.Title = "Bridge";
+
+ var builder = Host.CreateApplicationBuilder();
+ var bridgeConfiguration = new BridgeConfiguration();
+
+ #region endpoint-adding-simple
+
+ var learningLeft = new BridgeTransport(new LearningTransport());
+ learningLeft.HasEndpoint("Samples.Bridge.LeftSender");
+
+ #endregion
+
+ var learningTransport = new LearningTransport
+ {
+ // Set storage directory and add the character '2' to simulate a different transport.
+ StorageDirectory = $"{LearningTransportInfrastructure.FindStoragePath()}2"
+ };
+ var learningRight = new BridgeTransport(learningTransport)
+ {
+ // A different name is required if transports are used twice.
+ Name = "right-side"
+ };
+
+ #region endpoint-adding-register-publisher-by-string
+
+ var rightReceiver = new BridgeEndpoint("Samples.Bridge.RightReceiver");
+ rightReceiver.RegisterPublisher("OrderReceived", "Samples.Bridge.LeftSender");
+
+ #endregion
+ learningRight.HasEndpoint(rightReceiver);
+
+ #region add-transports-to-bridge
+
+ bridgeConfiguration.AddTransport(learningLeft);
+ bridgeConfiguration.AddTransport(learningRight);
+
+ #endregion
+
+ builder.Logging.ClearProviders();
+ builder.Logging.AddSimpleConsole(options =>
+ {
+ options.IncludeScopes = false;
+ options.SingleLine = true;
+ options.TimestampFormat = "hh:mm:ss ";
+ });
+
+ builder.UseNServiceBusBridge(bridgeConfiguration);
+
+ var host = builder.Build();
+ await host.RunAsync();
+ }
+}
\ No newline at end of file
diff --git a/samples/bridge/simple/Bridge_4/LeftReceiver/LeftReceiver.csproj b/samples/bridge/simple/Bridge_4/LeftReceiver/LeftReceiver.csproj
new file mode 100644
index 00000000000..adb24c4279b
--- /dev/null
+++ b/samples/bridge/simple/Bridge_4/LeftReceiver/LeftReceiver.csproj
@@ -0,0 +1,19 @@
+
+
+
+ net10.0
+ Exe
+ preview
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/bridge/simple/Bridge_4/LeftReceiver/OrderReceivedHandler.cs b/samples/bridge/simple/Bridge_4/LeftReceiver/OrderReceivedHandler.cs
new file mode 100644
index 00000000000..a25a6d453f7
--- /dev/null
+++ b/samples/bridge/simple/Bridge_4/LeftReceiver/OrderReceivedHandler.cs
@@ -0,0 +1,13 @@
+using System.Threading.Tasks;
+using NServiceBus;
+using Microsoft.Extensions.Logging;
+
+public class OrderReceivedHandler(ILogger logger) :
+ IHandleMessages
+{
+ public Task Handle(OrderReceived message, IMessageHandlerContext context)
+ {
+ logger.LogInformation("Subscriber has received OrderReceived event with OrderId {OrderId}.", message.OrderId);
+ return Task.CompletedTask;
+ }
+}
\ No newline at end of file
diff --git a/samples/bridge/simple/Bridge_4/LeftReceiver/Program.cs b/samples/bridge/simple/Bridge_4/LeftReceiver/Program.cs
new file mode 100644
index 00000000000..90f5de4967b
--- /dev/null
+++ b/samples/bridge/simple/Bridge_4/LeftReceiver/Program.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Hosting;
+using NServiceBus;
+
+Console.Title = "LeftReceiver";
+
+var builder = Host.CreateApplicationBuilder(args);
+
+var endpointConfiguration = new EndpointConfiguration("Samples.Bridge.LeftReceiver");
+endpointConfiguration.UsePersistence();
+endpointConfiguration.UseSerialization();
+endpointConfiguration.UseTransport(new LearningTransport());
+
+endpointConfiguration.Conventions().DefiningMessagesAs(t => t.Name == "OrderResponse");
+endpointConfiguration.Conventions().DefiningEventsAs(t => t.Name == "OrderReceived");
+
+endpointConfiguration.SendFailedMessagesTo("error");
+endpointConfiguration.EnableInstallers();
+
+
+Console.WriteLine("Press any key, the application is starting");
+Console.ReadKey();
+Console.WriteLine("Starting...");
+
+builder.UseNServiceBus(endpointConfiguration);
+await builder.Build().RunAsync();
diff --git a/samples/bridge/simple/Bridge_4/LeftSender/LeftSender.csproj b/samples/bridge/simple/Bridge_4/LeftSender/LeftSender.csproj
new file mode 100644
index 00000000000..f7f660478f6
--- /dev/null
+++ b/samples/bridge/simple/Bridge_4/LeftSender/LeftSender.csproj
@@ -0,0 +1,16 @@
+
+
+ net10.0
+ Exe
+ preview
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/bridge/simple/Bridge_4/LeftSender/OrderResponseHandler.cs b/samples/bridge/simple/Bridge_4/LeftSender/OrderResponseHandler.cs
new file mode 100644
index 00000000000..bf765b9f958
--- /dev/null
+++ b/samples/bridge/simple/Bridge_4/LeftSender/OrderResponseHandler.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Threading.Tasks;
+using NServiceBus;
+
+public class OrderResponseHandler : IHandleMessages
+{
+ public Task Handle(OrderResponse message, IMessageHandlerContext context)
+ {
+ Console.WriteLine($"OrderResponse Reply received with Id {message.OrderId}");
+
+ return Task.CompletedTask;
+ }
+}
\ No newline at end of file
diff --git a/samples/bridge/simple/Bridge_4/LeftSender/Program.cs b/samples/bridge/simple/Bridge_4/LeftSender/Program.cs
new file mode 100644
index 00000000000..fe0ddb20959
--- /dev/null
+++ b/samples/bridge/simple/Bridge_4/LeftSender/Program.cs
@@ -0,0 +1,66 @@
+using System;
+using System.Threading.Tasks;
+using NServiceBus;
+
+static class Program
+{
+ static async Task Main()
+ {
+ Console.Title = "LeftSender";
+ var endpointConfiguration = new EndpointConfiguration("Samples.Bridge.LeftSender");
+ endpointConfiguration.UsePersistence();
+
+ endpointConfiguration.Conventions().DefiningCommandsAs(t => t.Name == "PlaceOrder");
+ endpointConfiguration.Conventions().DefiningMessagesAs(t => t.Name == "OrderResponse");
+ endpointConfiguration.Conventions().DefiningEventsAs(t => t.Name == "OrderReceived");
+
+ endpointConfiguration.UseSerialization();
+ var routing = endpointConfiguration.UseTransport(new LearningTransport());
+ routing.RouteToEndpoint(typeof(PlaceOrder), "Samples.Bridge.RightReceiver");
+
+ endpointConfiguration.SendFailedMessagesTo("error");
+ endpointConfiguration.EnableInstallers();
+
+ var endpointInstance = await Endpoint.Start(endpointConfiguration);
+ await Start(endpointInstance);
+ await endpointInstance.Stop();
+ }
+
+ static async Task Start(IEndpointInstance endpointInstance)
+ {
+ Console.WriteLine("Press '1' to send the PlaceOrder command");
+ Console.WriteLine("Press '2' to publish the OrderReceived event");
+ Console.WriteLine("Press 'esc' other key to exit");
+
+ while (true)
+ {
+ var key = Console.ReadKey();
+ Console.WriteLine();
+
+ var orderId = Guid.NewGuid();
+ switch (key.Key)
+ {
+ case ConsoleKey.D1:
+ case ConsoleKey.NumPad1:
+ var placeOrder = new PlaceOrder
+ {
+ OrderId = orderId
+ };
+ await endpointInstance.Send(placeOrder);
+ Console.WriteLine($"Send PlaceOrder Command with Id {orderId}");
+ break;
+ case ConsoleKey.D2:
+ case ConsoleKey.NumPad2:
+ var orderReceived = new OrderReceived
+ {
+ OrderId = orderId
+ };
+ await endpointInstance.Publish(orderReceived);
+ Console.WriteLine($"Published OrderReceived Event with Id {orderId}.");
+ break;
+ case ConsoleKey.Escape:
+ return;
+ }
+ }
+ }
+}
diff --git a/samples/bridge/simple/Bridge_4/RightReceiver/OrderReceivedHandler.cs b/samples/bridge/simple/Bridge_4/RightReceiver/OrderReceivedHandler.cs
new file mode 100644
index 00000000000..a25a6d453f7
--- /dev/null
+++ b/samples/bridge/simple/Bridge_4/RightReceiver/OrderReceivedHandler.cs
@@ -0,0 +1,13 @@
+using System.Threading.Tasks;
+using NServiceBus;
+using Microsoft.Extensions.Logging;
+
+public class OrderReceivedHandler(ILogger logger) :
+ IHandleMessages
+{
+ public Task Handle(OrderReceived message, IMessageHandlerContext context)
+ {
+ logger.LogInformation("Subscriber has received OrderReceived event with OrderId {OrderId}.", message.OrderId);
+ return Task.CompletedTask;
+ }
+}
\ No newline at end of file
diff --git a/samples/bridge/simple/Bridge_4/RightReceiver/PlaceOrderHandler.cs b/samples/bridge/simple/Bridge_4/RightReceiver/PlaceOrderHandler.cs
new file mode 100644
index 00000000000..37df72cbded
--- /dev/null
+++ b/samples/bridge/simple/Bridge_4/RightReceiver/PlaceOrderHandler.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Logging;
+using NServiceBus;
+
+public class PlaceOrderHandler(ILogger logger) : IHandleMessages
+{
+ public async Task Handle(PlaceOrder message, IMessageHandlerContext context)
+ {
+ logger.LogInformation("Received PlaceOrder Command with Id {OrderId}", message.OrderId);
+
+ await context.Reply(new OrderResponse { OrderId = message.OrderId });
+ }
+}
\ No newline at end of file
diff --git a/samples/bridge/simple/Bridge_4/RightReceiver/Program.cs b/samples/bridge/simple/Bridge_4/RightReceiver/Program.cs
new file mode 100644
index 00000000000..d7beb7322b2
--- /dev/null
+++ b/samples/bridge/simple/Bridge_4/RightReceiver/Program.cs
@@ -0,0 +1,38 @@
+using System;
+using System.IO;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Hosting;
+using NServiceBus;
+
+Console.Title = "RightReceiver";
+
+var builder = Host.CreateApplicationBuilder(args);
+
+var endpointConfiguration = new EndpointConfiguration("Samples.Bridge.RightReceiver");
+endpointConfiguration.UsePersistence();
+
+endpointConfiguration.Conventions().DefiningCommandsAs(t => t.Name == "PlaceOrder");
+endpointConfiguration.Conventions().DefiningMessagesAs(t => t.Name == "OrderResponse");
+endpointConfiguration.Conventions().DefiningEventsAs(t => t.Name == "OrderReceived");
+
+#region alternative-learning-transport
+var learningTransportDefinition = new LearningTransport
+{
+ // Set storage directory and add the character '2' to simulate a different transport.
+ StorageDirectory = $"{LearningTransportInfrastructure.FindStoragePath()}2"
+};
+endpointConfiguration.UseTransport(learningTransportDefinition);
+#endregion
+
+endpointConfiguration.UseSerialization();
+
+endpointConfiguration.SendFailedMessagesTo("error");
+endpointConfiguration.EnableInstallers();
+
+
+Console.WriteLine("Press any key, the application is starting");
+Console.ReadKey();
+Console.WriteLine("Starting...");
+
+builder.UseNServiceBus(endpointConfiguration);
+await builder.Build().RunAsync();
diff --git a/samples/bridge/simple/Bridge_4/RightReceiver/RightReceiver.csproj b/samples/bridge/simple/Bridge_4/RightReceiver/RightReceiver.csproj
new file mode 100644
index 00000000000..adb24c4279b
--- /dev/null
+++ b/samples/bridge/simple/Bridge_4/RightReceiver/RightReceiver.csproj
@@ -0,0 +1,19 @@
+
+
+
+ net10.0
+ Exe
+ preview
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/bridge/simple/Bridge_4/Shared/LearningTransportInfrastructure.cs b/samples/bridge/simple/Bridge_4/Shared/LearningTransportInfrastructure.cs
new file mode 100644
index 00000000000..164b1fb4cf2
--- /dev/null
+++ b/samples/bridge/simple/Bridge_4/Shared/LearningTransportInfrastructure.cs
@@ -0,0 +1,42 @@
+using System;
+using System.IO;
+using System.Reflection;
+
+public static class LearningTransportInfrastructure
+{
+ public static string FindStoragePath()
+ {
+ var directory = AppDomain.CurrentDomain.BaseDirectory;
+ var assemblyName = Assembly.GetCallingAssembly().GetName().Name.ToLowerInvariant();
+
+ while (true)
+ {
+
+
+ var learningTransportDirectory = Path.Combine(directory, DefaultLearningTransportDirectory);
+ if (Directory.Exists(learningTransportDirectory))
+ {
+ return learningTransportDirectory;
+ }
+
+ // This works for samples
+ if (directory.ToLowerInvariant().EndsWith(assemblyName))
+ {
+ var solutionFolder = Directory.GetParent(directory);
+ if (solutionFolder != null)
+ return Path.Combine(solutionFolder.FullName, DefaultLearningTransportDirectory);
+ }
+
+ var parent = Directory.GetParent(directory);
+
+ if (parent == null)
+ {
+ throw new Exception($"Unable to determine the storage directory path for the learning transport. Either create a '{DefaultLearningTransportDirectory}2' directory in one of this project’s parent directories, or specify the path explicitly using the 'StorageDirectory' property in the API.");
+ }
+
+ directory = parent.FullName;
+ }
+ }
+
+ const string DefaultLearningTransportDirectory = ".learningtransport";
+}
\ No newline at end of file
diff --git a/samples/bridge/simple/Bridge_4/Shared/OrderReceived.cs b/samples/bridge/simple/Bridge_4/Shared/OrderReceived.cs
new file mode 100644
index 00000000000..06b6ade7f04
--- /dev/null
+++ b/samples/bridge/simple/Bridge_4/Shared/OrderReceived.cs
@@ -0,0 +1,6 @@
+using System;
+
+public class OrderReceived
+{
+ public required Guid OrderId { get; set; }
+}
\ No newline at end of file
diff --git a/samples/bridge/simple/Bridge_4/Shared/OrderResponse.cs b/samples/bridge/simple/Bridge_4/Shared/OrderResponse.cs
new file mode 100644
index 00000000000..e191d7fbaf3
--- /dev/null
+++ b/samples/bridge/simple/Bridge_4/Shared/OrderResponse.cs
@@ -0,0 +1,6 @@
+using System;
+
+public class OrderResponse
+{
+ public required Guid OrderId { get; set; }
+}
\ No newline at end of file
diff --git a/samples/bridge/simple/Bridge_4/Shared/PlaceOrder.cs b/samples/bridge/simple/Bridge_4/Shared/PlaceOrder.cs
new file mode 100644
index 00000000000..53b081cdfad
--- /dev/null
+++ b/samples/bridge/simple/Bridge_4/Shared/PlaceOrder.cs
@@ -0,0 +1,6 @@
+using System;
+
+public class PlaceOrder
+{
+ public required Guid OrderId { get; set; }
+}
\ No newline at end of file
diff --git a/samples/bridge/simple/Bridge_4/Shared/Shared.csproj b/samples/bridge/simple/Bridge_4/Shared/Shared.csproj
new file mode 100644
index 00000000000..3e44602cd21
--- /dev/null
+++ b/samples/bridge/simple/Bridge_4/Shared/Shared.csproj
@@ -0,0 +1,8 @@
+
+
+
+ net10.0
+ preview
+
+
+
\ No newline at end of file
diff --git a/samples/bridge/simple/Bridge_4/prerelease.txt b/samples/bridge/simple/Bridge_4/prerelease.txt
new file mode 100644
index 00000000000..e69de29bb2d