diff --git a/samples/unobtrusive/Core_10/Client/Client.csproj b/samples/unobtrusive/Core_10/Client/Client.csproj new file mode 100644 index 00000000000..14df8df95c7 --- /dev/null +++ b/samples/unobtrusive/Core_10/Client/Client.csproj @@ -0,0 +1,24 @@ + + + + net10.0 + preview + Exe + enable + enable + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/unobtrusive/Core_10/Client/CommandSender.cs b/samples/unobtrusive/Core_10/Client/CommandSender.cs new file mode 100644 index 00000000000..0d3971aee86 --- /dev/null +++ b/samples/unobtrusive/Core_10/Client/CommandSender.cs @@ -0,0 +1,86 @@ +using Commands; +using Messages; + +public class CommandSender +{ + public static async Task Start(IMessageSession messageSession) + { + Console.WriteLine("Press 'C' to send a command"); + Console.WriteLine("Press 'R' to send a request"); + Console.WriteLine("Press 'D' to send a large message that is marked to be sent using data bus"); + Console.WriteLine("Press 'X' to send a message that is marked with expiration time."); + Console.WriteLine("Press any other key to exit"); + + while (true) + { + var key = Console.ReadKey(); + Console.WriteLine(); + + switch (key.Key) + { + case ConsoleKey.C: + await SendCommand(messageSession); + continue; + case ConsoleKey.R: + await SendRequest(messageSession); + continue; + case ConsoleKey.D: + await Data(messageSession); + continue; + case ConsoleKey.X: + await Expiration(messageSession); + continue; + } + return; + + } + } + + // Shut down server before sending this message, after 30 seconds, the message will be moved to Transactional dead-letter messages queue. + static Task Expiration(IMessageSession messageSession) + { + var messageThatExpires = new MessageThatExpires + { + RequestId = Guid.NewGuid() + }; + Console.WriteLine("message with expiration was sent"); + return messageSession.Send("Samples.Unobtrusive.Server", messageThatExpires); + } + + static Task Data(IMessageSession messageSession) + { + var requestId = Guid.NewGuid(); + + var largeMessage = new LargeMessage + { + RequestId = requestId, + LargeDataBus = new byte[1024 * 1024 * 5] + }; + Console.WriteLine($"Request sent id: {requestId}"); + return messageSession.Send("Samples.Unobtrusive.Server", largeMessage); + } + + static Task SendRequest(IMessageSession messageSession) + { + var requestId = Guid.NewGuid(); + + var request = new Request + { + RequestId = requestId + }; + Console.WriteLine($"Request sent id: {requestId}"); + return messageSession.Send("Samples.Unobtrusive.Server", request); + } + + static Task SendCommand(IMessageSession messageSession) + { + var commandId = Guid.NewGuid(); + + var myCommand = new MyCommand + { + CommandId = commandId, + }; + Console.WriteLine($"Command sent id: {commandId}"); + return messageSession.Send("Samples.Unobtrusive.Server", myCommand); + } +} \ No newline at end of file diff --git a/samples/unobtrusive/Core_10/Client/InputLoopService.cs b/samples/unobtrusive/Core_10/Client/InputLoopService.cs new file mode 100644 index 00000000000..e4b98fae8e9 --- /dev/null +++ b/samples/unobtrusive/Core_10/Client/InputLoopService.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Extensions.Hosting; +using NServiceBus.Routing; + +namespace Client +{ + public class InputLoopService(IMessageSession messageSession) : BackgroundService + { + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + await CommandSender.Start(messageSession); + + } + } +} diff --git a/samples/unobtrusive/Core_10/Client/MyEventHandler.cs b/samples/unobtrusive/Core_10/Client/MyEventHandler.cs new file mode 100644 index 00000000000..ac8afec0e54 --- /dev/null +++ b/samples/unobtrusive/Core_10/Client/MyEventHandler.cs @@ -0,0 +1,11 @@ +using Events; +using Microsoft.Extensions.Logging; + +public class MyEventHandler(ILogger logger) : IHandleMessages +{ + public Task Handle(MyEvent message, IMessageHandlerContext context) + { + logger.LogInformation("MyEvent received from server with id:{EventId}", message.EventId); + return Task.CompletedTask; + } +} \ No newline at end of file diff --git a/samples/unobtrusive/Core_10/Client/Program.cs b/samples/unobtrusive/Core_10/Client/Program.cs new file mode 100644 index 00000000000..8a5c0b225d1 --- /dev/null +++ b/samples/unobtrusive/Core_10/Client/Program.cs @@ -0,0 +1,20 @@ +using Client; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; + +Console.Title = "Client"; +var builder = Host.CreateApplicationBuilder(args); +builder.Services.AddHostedService(); +var endpointConfiguration = new EndpointConfiguration("Samples.Unobtrusive.Client"); +endpointConfiguration.UseSerialization(); +endpointConfiguration.UseTransport(new LearningTransport()); +#pragma warning disable CS0618 // Type or member is obsolete +var dataBus = endpointConfiguration.UseDataBus(); +dataBus.BasePath(@"..\..\..\..\DataBusShare\"); +#pragma warning restore CS0618 // Type or member is obsolete + +endpointConfiguration.ApplyCustomConventions(); + +builder.UseNServiceBus(endpointConfiguration); + +await builder.Build().RunAsync(); \ No newline at end of file diff --git a/samples/unobtrusive/Core_10/Client/ResponseHandler.cs b/samples/unobtrusive/Core_10/Client/ResponseHandler.cs new file mode 100644 index 00000000000..fda742d912d --- /dev/null +++ b/samples/unobtrusive/Core_10/Client/ResponseHandler.cs @@ -0,0 +1,11 @@ +using Messages; +using Microsoft.Extensions.Logging; + +public class ResponseHandler(ILogger logger) : IHandleMessages +{ + public Task Handle(Response message, IMessageHandlerContext context) + { + logger.LogInformation("Response received from server for request with id:{ResponseId}", message.ResponseId); + return Task.CompletedTask; + } +} \ No newline at end of file diff --git a/samples/unobtrusive/Core_10/ConventionExtensions.cs b/samples/unobtrusive/Core_10/ConventionExtensions.cs new file mode 100644 index 00000000000..1967efdb1b4 --- /dev/null +++ b/samples/unobtrusive/Core_10/ConventionExtensions.cs @@ -0,0 +1,38 @@ +public static class ConventionExtensions +{ + #region CustomConvention + + public static void ApplyCustomConventions(this EndpointConfiguration endpointConfiguration) + { + var conventions = endpointConfiguration.Conventions(); + + conventions.DefiningCommandsAs( + type => + type.Namespace != null && + type.Namespace.EndsWith("Commands")); + + conventions.DefiningEventsAs( + type => + type.Namespace != null && + type.Namespace.EndsWith("Events")); + + conventions.DefiningMessagesAs( + type => type.Namespace == "Messages"); +#pragma warning disable CS0618 // Type or member is obsolete + conventions.DefiningDataBusPropertiesAs( + property => property.Name.EndsWith("DataBus")); +#pragma warning restore CS0618 // Type or member is obsolete + + conventions.DefiningTimeToBeReceivedAs( + type => + { + if (type.Name.EndsWith("Expires")) + { + return TimeSpan.FromSeconds(30); + } + return TimeSpan.MaxValue; + }); + } + + #endregion +} \ No newline at end of file diff --git a/samples/unobtrusive/Core_10/Server/CommandSender.cs b/samples/unobtrusive/Core_10/Server/CommandSender.cs new file mode 100644 index 00000000000..faa62b6f4a4 --- /dev/null +++ b/samples/unobtrusive/Core_10/Server/CommandSender.cs @@ -0,0 +1,36 @@ +using Events; + +class CommandSender +{ + public static async Task Start(IMessageSession messageSession) + { + Console.WriteLine("Press 'E' to publish an event"); + Console.WriteLine("Press any other key to exit"); + + while (true) + { + var key = Console.ReadKey(); + Console.WriteLine(); + + switch (key.Key) + { + case ConsoleKey.E: + await PublishEvent(messageSession); + continue; + } + return; + } + } + + static Task PublishEvent(IMessageSession messageSession) + { + var eventId = Guid.NewGuid(); + + Console.WriteLine($"Event published, id: {eventId}"); + var myEvent = new MyEvent + { + EventId = eventId + }; + return messageSession.Publish(myEvent); + } +} \ No newline at end of file diff --git a/samples/unobtrusive/Core_10/Server/InputLoopService.cs b/samples/unobtrusive/Core_10/Server/InputLoopService.cs new file mode 100644 index 00000000000..0ce3dea9e94 --- /dev/null +++ b/samples/unobtrusive/Core_10/Server/InputLoopService.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Extensions.Hosting; + +namespace Server +{ + public class InputLoopService(IMessageSession messageSession) : BackgroundService + { + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + await CommandSender.Start(messageSession); + } + } +} diff --git a/samples/unobtrusive/Core_10/Server/LargeMessageHandler.cs b/samples/unobtrusive/Core_10/Server/LargeMessageHandler.cs new file mode 100644 index 00000000000..eba77ce2413 --- /dev/null +++ b/samples/unobtrusive/Core_10/Server/LargeMessageHandler.cs @@ -0,0 +1,18 @@ +using Messages; +using Microsoft.Extensions.Logging; + +public class LargeMessageHandler(ILogger logger) : IHandleMessages +{ + public Task Handle(LargeMessage message, IMessageHandlerContext context) + { + if (message.LargeDataBus == null) + { + logger.LogInformation("Message [{MessageType}] received, id:{RequestId}", message.GetType(), message.RequestId); + } + else + { + logger.LogInformation("Message [{MessageType}] received, id:{RequestId} and payload {PayloadLength} bytes", message.GetType(), message.RequestId, message.LargeDataBus.Length); + } + return Task.CompletedTask; + } +} diff --git a/samples/unobtrusive/Core_10/Server/MessageThatExpiresHandler.cs b/samples/unobtrusive/Core_10/Server/MessageThatExpiresHandler.cs new file mode 100644 index 00000000000..1ae9e2bc11e --- /dev/null +++ b/samples/unobtrusive/Core_10/Server/MessageThatExpiresHandler.cs @@ -0,0 +1,12 @@ +using Messages; +using Microsoft.Extensions.Logging; + +public class MessageThatExpiresHandler(ILogger logger) : IHandleMessages +{ + + public Task Handle(MessageThatExpires message, IMessageHandlerContext context) + { + logger.LogInformation("Message [{MessageType}] received, id: [{RequestId}]", message.GetType(), message.RequestId); + return Task.CompletedTask; + } +} \ No newline at end of file diff --git a/samples/unobtrusive/Core_10/Server/MyCommandHandler.cs b/samples/unobtrusive/Core_10/Server/MyCommandHandler.cs new file mode 100644 index 00000000000..f9adf73e4f3 --- /dev/null +++ b/samples/unobtrusive/Core_10/Server/MyCommandHandler.cs @@ -0,0 +1,11 @@ +using Commands; +using Microsoft.Extensions.Logging; + +public class MyCommandHandler(ILogger logger) : IHandleMessages +{ + public Task Handle(MyCommand message, IMessageHandlerContext context) + { + logger.LogInformation("Command received, id:{CommandId}", message.CommandId); + return Task.CompletedTask; + } +} \ No newline at end of file diff --git a/samples/unobtrusive/Core_10/Server/Program.cs b/samples/unobtrusive/Core_10/Server/Program.cs new file mode 100644 index 00000000000..06ea8e86d66 --- /dev/null +++ b/samples/unobtrusive/Core_10/Server/Program.cs @@ -0,0 +1,21 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Server; + +Console.Title = "Server"; +var builder = Host.CreateApplicationBuilder(args); +builder.Services.AddHostedService(); + +var endpointConfiguration = new EndpointConfiguration("Samples.Unobtrusive.Server"); +endpointConfiguration.UseSerialization(); +endpointConfiguration.UseTransport(new LearningTransport()); +#pragma warning disable CS0618 // Type or member is obsolete +endpointConfiguration.UseDataBus() + .BasePath(@"..\..\..\..\DataBusShare\"); +#pragma warning restore CS0618 // Type or member is obsolete + +endpointConfiguration.ApplyCustomConventions(); + +builder.UseNServiceBus(endpointConfiguration); + +await builder.Build().RunAsync(); diff --git a/samples/unobtrusive/Core_10/Server/RequestMessageHandler.cs b/samples/unobtrusive/Core_10/Server/RequestMessageHandler.cs new file mode 100644 index 00000000000..f9984928311 --- /dev/null +++ b/samples/unobtrusive/Core_10/Server/RequestMessageHandler.cs @@ -0,0 +1,15 @@ +using Messages; +using Microsoft.Extensions.Logging; +public class RequestMessageHandler(ILogger logger) : IHandleMessages +{ + public Task Handle(Request message, IMessageHandlerContext context) + { + logger.LogInformation("Request received with id:{RequestId}", message.RequestId); + + var response = new Response + { + ResponseId = message.RequestId + }; + return context.Reply(response); + } +} \ No newline at end of file diff --git a/samples/unobtrusive/Core_10/Server/Server.csproj b/samples/unobtrusive/Core_10/Server/Server.csproj new file mode 100644 index 00000000000..e8f718d6336 --- /dev/null +++ b/samples/unobtrusive/Core_10/Server/Server.csproj @@ -0,0 +1,24 @@ + + + + net10.0 + preview + Exe + enable + enable + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/unobtrusive/Core_10/Shared/LargeMessage.cs b/samples/unobtrusive/Core_10/Shared/LargeMessage.cs new file mode 100644 index 00000000000..5d40788e982 --- /dev/null +++ b/samples/unobtrusive/Core_10/Shared/LargeMessage.cs @@ -0,0 +1,10 @@ +namespace Messages; + +using System; + +public class LargeMessage +{ + public Guid RequestId { get; set; } + + public byte[]? LargeDataBus { get; set; } +} diff --git a/samples/unobtrusive/Core_10/Shared/MessageThatExpires.cs b/samples/unobtrusive/Core_10/Shared/MessageThatExpires.cs new file mode 100644 index 00000000000..75d589a6583 --- /dev/null +++ b/samples/unobtrusive/Core_10/Shared/MessageThatExpires.cs @@ -0,0 +1,8 @@ +namespace Messages; + +using System; + +public class MessageThatExpires +{ + public Guid RequestId { get; set; } +} diff --git a/samples/unobtrusive/Core_10/Shared/MyCommand.cs b/samples/unobtrusive/Core_10/Shared/MyCommand.cs new file mode 100644 index 00000000000..ca9fdfd028f --- /dev/null +++ b/samples/unobtrusive/Core_10/Shared/MyCommand.cs @@ -0,0 +1,8 @@ +namespace Commands; + +using System; + +public class MyCommand +{ + public Guid CommandId { get; set; } +} diff --git a/samples/unobtrusive/Core_10/Shared/MyEvent.cs b/samples/unobtrusive/Core_10/Shared/MyEvent.cs new file mode 100644 index 00000000000..a34d1bdd8e2 --- /dev/null +++ b/samples/unobtrusive/Core_10/Shared/MyEvent.cs @@ -0,0 +1,8 @@ +namespace Events; + +using System; + +public class MyEvent +{ + public Guid EventId { get; set; } +} diff --git a/samples/unobtrusive/Core_10/Shared/Request.cs b/samples/unobtrusive/Core_10/Shared/Request.cs new file mode 100644 index 00000000000..4d57e5960cc --- /dev/null +++ b/samples/unobtrusive/Core_10/Shared/Request.cs @@ -0,0 +1,8 @@ +namespace Messages; + +using System; + +public class Request +{ + public Guid RequestId { get; set; } +} diff --git a/samples/unobtrusive/Core_10/Shared/Response.cs b/samples/unobtrusive/Core_10/Shared/Response.cs new file mode 100644 index 00000000000..e746c5e9f00 --- /dev/null +++ b/samples/unobtrusive/Core_10/Shared/Response.cs @@ -0,0 +1,8 @@ +namespace Messages; + +using System; + +public class Response +{ + public Guid ResponseId { get; set; } +} \ No newline at end of file diff --git a/samples/unobtrusive/Core_10/Shared/Shared.csproj b/samples/unobtrusive/Core_10/Shared/Shared.csproj new file mode 100644 index 00000000000..fb02879bdbf --- /dev/null +++ b/samples/unobtrusive/Core_10/Shared/Shared.csproj @@ -0,0 +1,10 @@ + + + + net10.0 + preview + enable + enable + + + \ No newline at end of file diff --git a/samples/unobtrusive/Core_10/Unobtrusive.sln b/samples/unobtrusive/Core_10/Unobtrusive.sln new file mode 100644 index 00000000000..a243791955e --- /dev/null +++ b/samples/unobtrusive/Core_10/Unobtrusive.sln @@ -0,0 +1,29 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29728.190 +MinimumVisualStudioVersion = 15.0.26730.12 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Client", "Client\Client.csproj", "{476D0A88-E281-4BC8-9617-93E53C1F9FE6}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Server", "Server\Server.csproj", "{75424F0A-458B-42DA-9DDD-600367893A93}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Shared", "Shared\Shared.csproj", "{DD0DC12D-D6DF-47C0-B75A-AEC351164196}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {476D0A88-E281-4BC8-9617-93E53C1F9FE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {476D0A88-E281-4BC8-9617-93E53C1F9FE6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {75424F0A-458B-42DA-9DDD-600367893A93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {75424F0A-458B-42DA-9DDD-600367893A93}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DD0DC12D-D6DF-47C0-B75A-AEC351164196}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DD0DC12D-D6DF-47C0-B75A-AEC351164196}.Debug|Any CPU.Build.0 = Debug|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {9FC8A922-FADC-447B-BA38-9F47C3FBB51C} + EndGlobalSection +EndGlobal diff --git a/samples/unobtrusive/Core_10/prerelease.txt b/samples/unobtrusive/Core_10/prerelease.txt new file mode 100644 index 00000000000..e69de29bb2d