├── .gitignore ├── MessageContracts ├── MessageContracts.csproj ├── OrderAccepted.cs ├── OrderItem.cs └── SubmitOrder.cs ├── README.md ├── Sample-RequestResponse.sln ├── Sample-RequestResponse ├── MessageQueueService.cs ├── Program.cs └── Sample-RequestResponse.csproj └── WebApplication1 ├── Item.cs ├── Order.cs ├── Program.cs ├── Startup.cs ├── WebApplication1.csproj └── appsettings.json /.gitignore: -------------------------------------------------------------------------------- 1 | build_output/* 2 | build_artifacts/* 3 | build_temp/* 4 | *.suo 5 | *.user 6 | packages 7 | *.dotCover 8 | 9 | *.ncrunch* 10 | .vs 11 | 12 | .fake 13 | 14 | src/logs/* 15 | 16 | **/*.sln* 17 | bin 18 | obj 19 | _ReSharper* 20 | 21 | *.csproj.user 22 | *.resharper.user 23 | *.resharper 24 | *.ReSharper 25 | *.cache 26 | *~ 27 | *.swp 28 | *.bak 29 | *.orig 30 | 31 | NuGet.exe 32 | packages 33 | 34 | # Tests 35 | TestResult.xml 36 | submit.xml 37 | tests/* 38 | SolutionVersion.cs 39 | src/SolutionVersion.cs 40 | tests 41 | doc/build/* 42 | *.[lm]df 43 | 44 | # osx noise 45 | .DS_Store 46 | *.DotSettings 47 | /src/MassTransit.SimpleInjectorIntegration/MassTransit.SimpleInjectorIntegration.csproj.nuspec 48 | *.DS_Store 49 | 50 | _book 51 | /node_modules 52 | .vscode 53 | **/.idea/ -------------------------------------------------------------------------------- /MessageContracts/MessageContracts.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | netstandard2.0 4 | 5 | -------------------------------------------------------------------------------- /MessageContracts/OrderAccepted.cs: -------------------------------------------------------------------------------- 1 | namespace MessageContracts 2 | { 3 | public interface OrderAccepted 4 | { 5 | string OrderId { get; } 6 | } 7 | } -------------------------------------------------------------------------------- /MessageContracts/OrderItem.cs: -------------------------------------------------------------------------------- 1 | namespace MessageContracts 2 | { 3 | public interface OrderItem 4 | { 5 | string OrderId { get; } 6 | } 7 | } -------------------------------------------------------------------------------- /MessageContracts/SubmitOrder.cs: -------------------------------------------------------------------------------- 1 | namespace MessageContracts 2 | { 3 | public interface SubmitOrder 4 | { 5 | string OrderId { get; } 6 | } 7 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sample Request/Response 2 | 3 | This sample demonstrates how to build a controller using ASP.NET Core and a complementary .NET Core Console application to send a request from a controller, which is handled by the console application. 4 | 5 | Everything is async, marvelous, and built entirely on a Mac using JetBrains Rider. 6 | 7 | Should just be able to go into the appropriate folders and `dotnet run` each project. 8 | 9 | RabbitMQ should be running on your Mac, using the default port and the _guest_ user account, otherwise you'll need to make changes. 10 | 11 | Enjoy! 12 | -------------------------------------------------------------------------------- /Sample-RequestResponse.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample-RequestResponse", "Sample-RequestResponse\Sample-RequestResponse.csproj", "{E9E2C393-A1CE-4CD0-A664-D106CE4763D4}" 4 | EndProject 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebApplication1", "WebApplication1\WebApplication1.csproj", "{A63C388E-364D-483C-9D79-E4DFAA4B73D6}" 6 | EndProject 7 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MessageContracts", "MessageContracts\MessageContracts.csproj", "{02B1B2F2-86F7-46FC-BFB0-C451FE54E737}" 8 | EndProject 9 | Global 10 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 11 | Debug|Any CPU = Debug|Any CPU 12 | Release|Any CPU = Release|Any CPU 13 | EndGlobalSection 14 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 15 | {E9E2C393-A1CE-4CD0-A664-D106CE4763D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 16 | {E9E2C393-A1CE-4CD0-A664-D106CE4763D4}.Debug|Any CPU.Build.0 = Debug|Any CPU 17 | {E9E2C393-A1CE-4CD0-A664-D106CE4763D4}.Release|Any CPU.ActiveCfg = Release|Any CPU 18 | {E9E2C393-A1CE-4CD0-A664-D106CE4763D4}.Release|Any CPU.Build.0 = Release|Any CPU 19 | {A63C388E-364D-483C-9D79-E4DFAA4B73D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 20 | {A63C388E-364D-483C-9D79-E4DFAA4B73D6}.Debug|Any CPU.Build.0 = Debug|Any CPU 21 | {A63C388E-364D-483C-9D79-E4DFAA4B73D6}.Release|Any CPU.ActiveCfg = Release|Any CPU 22 | {A63C388E-364D-483C-9D79-E4DFAA4B73D6}.Release|Any CPU.Build.0 = Release|Any CPU 23 | {02B1B2F2-86F7-46FC-BFB0-C451FE54E737}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 24 | {02B1B2F2-86F7-46FC-BFB0-C451FE54E737}.Debug|Any CPU.Build.0 = Debug|Any CPU 25 | {02B1B2F2-86F7-46FC-BFB0-C451FE54E737}.Release|Any CPU.ActiveCfg = Release|Any CPU 26 | {02B1B2F2-86F7-46FC-BFB0-C451FE54E737}.Release|Any CPU.Build.0 = Release|Any CPU 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /Sample-RequestResponse/MessageQueueService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using System.Threading.Tasks; 4 | using MassTransit; 5 | using MessageContracts; 6 | using Microsoft.Extensions.Hosting; 7 | 8 | namespace Sample_RequestResponse 9 | { 10 | public class MessageQueueService : BackgroundService 11 | { 12 | readonly IBusControl _bus; 13 | 14 | public MessageQueueService() 15 | { 16 | _bus = Bus.Factory.CreateUsingRabbitMq(cfg => 17 | { 18 | cfg.Host(new Uri("rabbitmq://localhost/"), h => { }); 19 | 20 | cfg.ReceiveEndpoint("order-service", e => 21 | { 22 | e.Handler(context => 23 | { 24 | Console.WriteLine("Order: {0}", context.Message.OrderId); 25 | 26 | return context.RespondAsync(new 27 | { 28 | context.Message.OrderId 29 | }); 30 | }); 31 | }); 32 | }); 33 | } 34 | 35 | protected override Task ExecuteAsync(CancellationToken stoppingToken) 36 | { 37 | return _bus.StartAsync(stoppingToken); 38 | } 39 | 40 | public override Task StopAsync(CancellationToken cancellationToken) 41 | { 42 | return Task.WhenAll(base.StopAsync(cancellationToken), _bus.StopAsync(cancellationToken)); 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /Sample-RequestResponse/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.DependencyInjection; 2 | using Microsoft.Extensions.Hosting; 3 | using System.Threading.Tasks; 4 | 5 | namespace Sample_RequestResponse 6 | { 7 | class Program 8 | { 9 | static async Task Main(string[] args) 10 | { 11 | var builder = new HostBuilder() 12 | .ConfigureServices((hostContext, services) => 13 | { 14 | services.AddHostedService(); 15 | }); 16 | 17 | await builder 18 | .RunConsoleAsync(); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /Sample-RequestResponse/Sample-RequestResponse.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | Exe 4 | netcoreapp3.1 5 | 7.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | {02B1B2F2-86F7-46FC-BFB0-C451FE54E737} 14 | MessageContracts 15 | 16 | 17 | -------------------------------------------------------------------------------- /WebApplication1/Item.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using System.Threading.Tasks; 4 | using MassTransit; 5 | using MessageContracts; 6 | using Microsoft.AspNetCore.Mvc; 7 | 8 | namespace WebApplication1 9 | { 10 | [Route("api/item")] 11 | public class Item : Controller 12 | { 13 | readonly ISendEndpointProvider _sendEndpointProvider; 14 | 15 | public Item(ISendEndpointProvider sendEndpointProvider) 16 | { 17 | _sendEndpointProvider = sendEndpointProvider; 18 | } 19 | 20 | [HttpPut("{id}")] 21 | public async Task Submit(string id, CancellationToken cancellationToken) 22 | { 23 | var endpoint = await _sendEndpointProvider.GetSendEndpoint(new Uri("queue:item-notification")); 24 | 25 | await endpoint.Send(new 26 | { 27 | OrderId = id 28 | }, cancellationToken); 29 | 30 | return Ok(new {Orderid = id}); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /WebApplication1/Order.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | using System.Threading; 3 | using System.Threading.Tasks; 4 | using MassTransit; 5 | using MessageContracts; 6 | using Microsoft.AspNetCore.Mvc; 7 | 8 | namespace WebApplication1 9 | { 10 | [Route("api/order")] 11 | public class Order : Controller 12 | { 13 | readonly IRequestClient _requestClient; 14 | 15 | public Order(IRequestClient requestClient) 16 | { 17 | _requestClient = requestClient; 18 | } 19 | 20 | [HttpPut("{id}")] 21 | public async Task Submit(string id, CancellationToken cancellationToken) 22 | { 23 | try 24 | { 25 | var result = await _requestClient.GetResponse(new {OrderId = id}, cancellationToken); 26 | 27 | return Accepted(new {result.Message.OrderId}); 28 | } 29 | catch (RequestTimeoutException) 30 | { 31 | return StatusCode((int) HttpStatusCode.RequestTimeout); 32 | } 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /WebApplication1/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore; 2 | using Microsoft.AspNetCore.Hosting; 3 | 4 | namespace WebApplication1 5 | { 6 | public class Program 7 | { 8 | public static void Main(string[] args) 9 | { 10 | BuildWebHost(args).Run(); 11 | } 12 | 13 | public static IWebHost BuildWebHost(string[] args) 14 | { 15 | return WebHost.CreateDefaultBuilder(args) 16 | .UseStartup() 17 | .Build(); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /WebApplication1/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MassTransit; 3 | using MessageContracts; 4 | using Microsoft.AspNetCore.Builder; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.DependencyInjection; 7 | using Microsoft.Extensions.Hosting; 8 | 9 | namespace WebApplication1 10 | { 11 | public class Startup 12 | { 13 | public void ConfigureServices(IServiceCollection services) 14 | { 15 | services.AddMvc(); 16 | 17 | services.AddMassTransit(x => 18 | { 19 | x.UsingRabbitMq((context, cfg) => cfg.Host("localhost")); 20 | 21 | var timeout = TimeSpan.FromSeconds(10); 22 | var serviceAddress = new Uri("rabbitmq://localhost/order-service"); 23 | 24 | x.AddRequestClient(serviceAddress, timeout); 25 | }); 26 | services.AddMassTransitHostedService(); 27 | } 28 | 29 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 30 | { 31 | if (env.IsDevelopment()) 32 | app.UseDeveloperExceptionPage(); 33 | 34 | app.UseRouting(); 35 | 36 | app.UseEndpoints(x => x.MapControllers()); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /WebApplication1/WebApplication1.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | netcoreapp3.1 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /WebApplication1/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "MassTransit": "Debug", 7 | "Microsoft.Hosting.Lifetime": "Information" 8 | } 9 | }, 10 | "AllowedHosts": "*" 11 | } 12 | --------------------------------------------------------------------------------