Skip to content

Commit

Permalink
Add Example06
Browse files Browse the repository at this point in the history
  • Loading branch information
aimenux committed Dec 7, 2024
1 parent cef81c2 commit 0fa3a4c
Show file tree
Hide file tree
Showing 15 changed files with 250 additions and 1 deletion.
3 changes: 3 additions & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
<CentralPackageTransitivePinningEnabled>false</CentralPackageTransitivePinningEnabled>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Azure.Identity" Version="1.13.1" />
<PackageVersion Include="Azure.Messaging.ServiceBus" Version="7.18.2" />
<PackageVersion Include="MassTransit.Azure.ServiceBus.Core" Version="8.3.3" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="8.0.1" />
<PackageVersion Include="Rebus.AzureServiceBus" Version="10.2.0" />
<PackageVersion Include="Rebus.ServiceProvider" Version="10.3.0" />
<PackageVersion Include="System.Text.Json" Version="8.0.5" />
<PackageVersion Include="WolverineFx.AzureServiceBus" Version="3.4.0" />
</ItemGroup>
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ Playing with service bus
> :four: `Example04` : use worker template with [MassTransit](https://masstransit-project.com)
>
> :five: `Example05` : use worker template with [Wolverine](https://wolverinefx.net)
>
> :six: `Example06` : use worker template with [Rebus](https://github.com/rebus-org/Rebus)
>
**`Tools`** : net 8.0, servicebus, masstransit, wolverine
**`Tools`** : net 8.0, servicebus, masstransit, wolverine, rebus
7 changes: 7 additions & 0 deletions ServiceBusDemo.sln
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example04", "src\Example04\
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example05", "src\Example05\Example05.csproj", "{18585800-512B-4E0B-88A5-C9556465F17E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example06", "src\Example06\Example06.csproj", "{BE698371-5D09-4AD0-8229-DCDA37D1D905}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -55,12 +57,17 @@ Global
{18585800-512B-4E0B-88A5-C9556465F17E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{18585800-512B-4E0B-88A5-C9556465F17E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{18585800-512B-4E0B-88A5-C9556465F17E}.Release|Any CPU.Build.0 = Release|Any CPU
{BE698371-5D09-4AD0-8229-DCDA37D1D905}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BE698371-5D09-4AD0-8229-DCDA37D1D905}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BE698371-5D09-4AD0-8229-DCDA37D1D905}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BE698371-5D09-4AD0-8229-DCDA37D1D905}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{1F1CAFDA-2CE5-4248-B437-512552BFF221} = {675A9474-CB75-4BB9-96ED-7A4F6DBF6DD8}
{35DB9CC1-DC4E-4891-A1C1-12A2BBA47E08} = {675A9474-CB75-4BB9-96ED-7A4F6DBF6DD8}
{C5AA6BD9-2F7B-4F7C-AE2E-3BAE12B34E29} = {675A9474-CB75-4BB9-96ED-7A4F6DBF6DD8}
{EFA5CB6E-D00C-450F-98BC-0A94B59A7AD4} = {675A9474-CB75-4BB9-96ED-7A4F6DBF6DD8}
{18585800-512B-4E0B-88A5-C9556465F17E} = {675A9474-CB75-4BB9-96ED-7A4F6DBF6DD8}
{BE698371-5D09-4AD0-8229-DCDA37D1D905} = {675A9474-CB75-4BB9-96ED-7A4F6DBF6DD8}
EndGlobalSection
EndGlobal
21 changes: 21 additions & 0 deletions src/Example06/Configuration/Settings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Azure.Messaging.ServiceBus;

namespace Example06.Configuration;

public sealed record Settings
{
public const string SectionName = "Settings";

public string QueueName { get; init; } = default!;
public string ConnectionString { get; init; } = default!;
public RetrySettings RetrySettings { get; init; } = new();
public TimeSpan ConsumerDelay { get; init; } = TimeSpan.FromSeconds(1);
public TimeSpan ProducerDelay { get; init; } = TimeSpan.FromSeconds(1);
public ServiceBusTransportType TransportType { get; init; } = ServiceBusTransportType.AmqpWebSockets;
}

public sealed record RetrySettings
{
public int RetryCount { get; init; } = 3;
public TimeSpan RetryDelay { get; init; } = TimeSpan.FromSeconds(5);
}
26 changes: 26 additions & 0 deletions src/Example06/Configuration/SettingsValidator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Microsoft.Extensions.Options;

namespace Example06.Configuration;

public sealed class SettingsValidator : IValidateOptions<Settings>
{
public ValidateOptionsResult Validate(string? name, Settings? settings)
{
if (settings is null)
{
return ValidateOptionsResult.Fail($"{nameof(Settings)} is required.");
}

if (string.IsNullOrWhiteSpace(settings.QueueName))
{
return ValidateOptionsResult.Fail($"{nameof(Settings.QueueName)} is required.");
}

if (string.IsNullOrWhiteSpace(settings.ConnectionString))
{
return ValidateOptionsResult.Fail($"{nameof(Settings.ConnectionString)} is required.");
}

return ValidateOptionsResult.Success;
}
}
26 changes: 26 additions & 0 deletions src/Example06/Consumers/MessageConsumer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Example06.Configuration;
using Example06.Contracts;
using Example06.Extensions;
using Microsoft.Extensions.Options;
using Rebus.Handlers;

namespace Example06.Consumers;

public sealed class MessageConsumer : IHandleMessages<Message>
{
private readonly Settings _settings;
private readonly ILogger<MessageConsumer> _logger;

public MessageConsumer(IOptions<Settings> options, ILogger<MessageConsumer> logger)
{
_settings = (options ?? throw new ArgumentNullException(nameof(options))).Value;
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}

public async Task Handle(Message message)
{
_logger.LogConsumedMessage(message.Id);

await Task.Delay(_settings.ConsumerDelay);
}
}
13 changes: 13 additions & 0 deletions src/Example06/Contracts/Message.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace Example06.Contracts;

public sealed record Message
{
public Guid Id { get; init; }
public string Text { get; init; }

public Message()
{
Id = Guid.NewGuid();
Text = $"Text for Id {Id}";
}
}
47 changes: 47 additions & 0 deletions src/Example06/DependencyInjection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using Example06.Configuration;
using Example06.Consumers;
using Example06.Contracts;
using Example06.Producers;
using Microsoft.Extensions.Options;
using Rebus.Config;
using Rebus.Routing.TypeBased;

namespace Example06;

public static class DependencyInjection
{
public static void AddServices(this HostApplicationBuilder builder)
{
builder.AddSettings();
builder.AddServiceBus();
}

private static void AddSettings(this HostApplicationBuilder builder)
{
builder.Services.Configure<Settings>(builder.Configuration.GetSection(Settings.SectionName));
builder.Services.AddSingleton<IValidateOptions<Settings>, SettingsValidator>();
}

private static void AddServiceBus(this HostApplicationBuilder builder)
{
var settings = builder.Configuration.GetSettings();

builder.Services.AddRebus(cfg =>
{
cfg.Transport(x => x.UseAzureServiceBus(settings.ConnectionString, settings.QueueName));
cfg.Routing(r => r.TypeBased().Map<Message>(settings.QueueName));
return cfg;
});

builder.Services.AddRebusHandler<MessageConsumer>();

builder.Services.AddHostedService<MessageProducer>();
}

private static Settings GetSettings(this ConfigurationManager configuration)
{
var settings = new Settings();
configuration.GetSection(Settings.SectionName).Bind(settings);
return settings;
}
}
14 changes: 14 additions & 0 deletions src/Example06/Example06.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk.Worker">

<PropertyGroup>
<UserSecretsId>ServiceBusDemo-Example06-UserSecrets</UserSecretsId>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Azure.Identity" />
<PackageReference Include="Microsoft.Extensions.Hosting" />
<PackageReference Include="Rebus.AzureServiceBus" />
<PackageReference Include="Rebus.ServiceProvider" />
</ItemGroup>

</Project>
10 changes: 10 additions & 0 deletions src/Example06/Extensions/LoggingExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Example06.Extensions;

public static partial class LoggingExtensions
{
[LoggerMessage(Level = LogLevel.Information, Message = "Message ({MessageId}) consumed.")]
public static partial void LogConsumedMessage(this ILogger logger, Guid messageId);

[LoggerMessage(Level = LogLevel.Information, Message = "Message ({MessageId}) produced.")]
public static partial void LogProducedMessage(this ILogger logger, Guid messageId);
}
35 changes: 35 additions & 0 deletions src/Example06/Producers/MessageProducer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using Example06.Configuration;
using Example06.Contracts;
using Example06.Extensions;
using Microsoft.Extensions.Options;
using Rebus.Bus;

namespace Example06.Producers;

public sealed class MessageProducer : BackgroundService
{
private readonly IServiceScopeFactory _factory;
private readonly Settings _settings;
private readonly ILogger<MessageProducer> _logger;

public MessageProducer(IServiceScopeFactory factory, IOptions<Settings> options, ILogger<MessageProducer> logger)
{
_factory = factory ?? throw new ArgumentNullException(nameof(factory));
_settings = (options ?? throw new ArgumentNullException(nameof(options))).Value;
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}

protected override async Task ExecuteAsync(CancellationToken cancellationToken)
{
using var scope = _factory.CreateScope();
using var bus = scope.ServiceProvider.GetRequiredService<IBus>();

while (!cancellationToken.IsCancellationRequested)
{
var message = new Message();
await bus.Send(message);
_logger.LogProducedMessage(message.Id);
await Task.Delay(_settings.ProducerDelay, cancellationToken);
}
}
}
6 changes: 6 additions & 0 deletions src/Example06/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
using Example06;

var builder = Host.CreateApplicationBuilder(args);
builder.AddServices();
var host = builder.Build();
await host.RunAsync();
12 changes: 12 additions & 0 deletions src/Example06/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"profiles": {
"Example06": {
"commandName": "Project",
"dotnetRunMessages": true,
"environmentVariables": {
"DOTNET_ENVIRONMENT": "Development"
}
}
}
}
8 changes: 8 additions & 0 deletions src/Example06/appsettings.Development.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.Hosting.Lifetime": "Warning"
}
}
}
19 changes: 19 additions & 0 deletions src/Example06/appsettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.Hosting.Lifetime": "Warning"
},
"Console": {
"FormatterName": "simple",
"FormatterOptions": {
"SingleLine": true,
"TimestampFormat": "HH:mm:ss.ffff "
}
}
},
"Settings": {
"QueueName": "example06-queue",
"ConnectionString": "Endpoint=sb://namespace.service-bus.windows.net"
}
}

0 comments on commit 0fa3a4c

Please sign in to comment.