• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mehdihadeli / food-delivery-microservices / 28686129952

03 Jul 2026 10:31PM UTC coverage: 17.028% (+0.8%) from 16.207%
28686129952

Pull #254

github

web-flow
Merge 245e1f02e into ed20d3c08
Pull Request #254: feat: :sparkles: add inbox, outbox and internal processor by wolverine

379 of 3330 branches covered (11.38%)

Branch coverage included in aggregate %.

19 of 61 new or added lines in 12 files covered. (31.15%)

29 existing lines in 5 files now uncovered.

1398 of 7106 relevant lines covered (19.67%)

0.41 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

68.75
/src/BuildingBlocks/BuildingBlocks.Integration.Wolverine/Extensions/DependencyInjectionExtensions.cs
1
using System.Reflection;
2
using BuildingBlocks.Abstractions.Messages;
3
using BuildingBlocks.Abstractions.Messages.MessagePersistence;
4
using BuildingBlocks.Core.Extensions;
5
using BuildingBlocks.Core.Extensions.HostApplicationBuilderExtensions;
6
using BuildingBlocks.Core.Extensions.ServiceCollectionExtensions;
7
using BuildingBlocks.Core.Web.Extensions;
8
using JasperFx.CodeGeneration.Model;
9
using Microsoft.Extensions.Configuration;
10
using Microsoft.Extensions.DependencyInjection.Extensions;
11
using Microsoft.Extensions.Hosting;
12
using RabbitMQ.Client;
13
using Wolverine;
14
using Wolverine.EntityFrameworkCore;
15
using Wolverine.Postgresql;
16
using Wolverine.RabbitMQ;
17
using Constants = BuildingBlocks.Core.Constants;
18

19
namespace BuildingBlocks.Integration.Wolverine.Extensions;
20

21
public static class DependencyInjectionExtensions
22
{
23
    public static IHostApplicationBuilder AddWolverineEventBus(
24
        this IHostApplicationBuilder builder,
25
        Action<WolverineOptions>? configureMessagesTopologies = null,
26
        Action<WolverineOptions>? configureBusRegistration = null,
27
        Action<WolverineBusOptions>? configureWolverineBusOptions = null,
28
        string? durabilityConnectionStringName = null,
29
        Assembly[]? assemblies = null
30
    )
31
    {
32
        assemblies ??= [Assembly.GetCallingAssembly()];
2!
33

34
        // Add option to the dependency injection
35
        builder.Services.AddValidationOptions(configurator: configureWolverineBusOptions);
2✔
36
        var wolverineBusOptions = builder.Configuration.BindOptions<WolverineBusOptions>();
2✔
37

38
        // - EnvironmentVariablesConfigurationProvider is injected by aspire and use to read configuration values from environment variables with `ConnectionStrings:redis` key on configuration.
39
        // The configuration provider handles these conversions automatically, and `__ (double underscore)` becomes `:` for nested sections, so environment configuration reads its data from the ` ConnectionStrings__redis ` environment. all envs are available in `Environment.GetEnvironmentVariables()`.
40
        // - For setting none sensitive configuration, we can use Aspire named configuration `Aspire:StackExchange:Redis:DisableHealthChecks` which is of type ConfigurationProvider and should be set in appsetting.json
41

42
        // https://learn.microsoft.com/en-us/dotnet/aspire/messaging/rabbitmq-integration?tabs=dotnet-cli#use-a-connection-strin
43
        // first read from aspire injected ConnectionString then read from config
44
        var connectionString =
2!
45
            builder.Configuration.GetConnectionString(Constants.AspireResources.Rabbitmq)
2✔
46
            ?? wolverineBusOptions.RabbitMQConnectionString
2✔
47
            ?? throw new InvalidOperationException(
2✔
48
                $"Connection string '{Constants.AspireResources.Rabbitmq}' or `{nameof(WolverineBusOptions)}.{nameof(WolverineBusOptions.RabbitMQConnectionString)}` not found."
2✔
49
            );
2✔
50

51
        builder
2✔
52
            .Services.AddOptions<HostOptions>()
2✔
53
            .Configure(options =>
2✔
54
            {
2✔
55
                options.StartupTimeout = TimeSpan.FromSeconds(60);
2✔
56
                options.ShutdownTimeout = TimeSpan.FromSeconds(60);
2✔
57
            });
2✔
58

59
        builder.Services.AddSingleton<IHostedService>(sp => new RabbitMqTopologyProvisioningHostedService(
×
60
            connectionString,
×
61
            sp.GetRequiredService<Microsoft.Extensions.Logging.ILogger<RabbitMqTopologyProvisioningHostedService>>()
×
62
        ));
×
63

64
        // will override default null messaging types - we should not use `TryAddTransient` to replace null types
65
        builder.Services.Replace(ServiceDescriptor.Transient<IExternalEventBus, WolverineEventBus>());
2✔
66
        builder.Services.Replace(ServiceDescriptor.Transient<IBusDirectPublisher, WolverineDirectPublisher>());
2✔
67
        builder.Services.Replace(
2✔
68
            ServiceDescriptor.Scoped<IMessagePersistenceService, WolverineMessagePersistenceService>()
2✔
69
        );
2✔
70

71
        ConfigureInstrumentation(builder, wolverineBusOptions, connectionString);
2✔
72

73
        builder.Services.AddWolverine(options =>
2✔
74
        {
2✔
75
            foreach (var assembly in assemblies)
2✔
76
            {
2✔
77
                options.Discovery.IncludeAssembly(assembly);
2✔
78
            }
2✔
79

2✔
80
            options.UseRuntimeCompilation();
2✔
81
            options.ServiceLocationPolicy = ServiceLocationPolicy.AllowedButWarn;
2✔
82

2✔
83
            configureBusRegistration?.Invoke(options);
2!
84

2✔
85
            ConfigureDurability(builder, options, wolverineBusOptions, durabilityConnectionStringName);
2✔
86

2✔
87
            options.UseRabbitMq(connectionString);
2✔
88

2✔
89
            configureMessagesTopologies?.Invoke(options);
2!
90
        });
2✔
91

92
        return builder;
2✔
93
    }
94

95
    private static void ConfigureDurability(
96
        IHostApplicationBuilder builder,
97
        WolverineOptions options,
98
        WolverineBusOptions wolverineBusOptions,
99
        string? durabilityConnectionStringName
100
    )
101
    {
102
        if (!wolverineBusOptions.EnableDurability)
2!
103
        {
104
            return;
2✔
105
        }
106

NEW
107
        var connectionString = !string.IsNullOrWhiteSpace(durabilityConnectionStringName)
×
NEW
108
            ? builder.Configuration.GetConnectionString(durabilityConnectionStringName)
×
NEW
109
            : null;
×
110

NEW
111
        if (string.IsNullOrWhiteSpace(connectionString))
×
112
        {
NEW
113
            throw new InvalidOperationException(
×
NEW
114
                $"Connection string '{durabilityConnectionStringName}' is required when Wolverine durability is enabled."
×
NEW
115
            );
×
116
        }
117

NEW
118
        options.PersistMessagesWithPostgresql(connectionString);
×
119

NEW
120
        if (wolverineBusOptions.UseEntityFrameworkCoreTransactions)
×
121
        {
NEW
122
            options.UseEntityFrameworkCoreTransactions();
×
123
        }
124

NEW
125
        if (wolverineBusOptions.UseDurableLocalQueues)
×
126
        {
NEW
127
            options.Policies.UseDurableLocalQueues();
×
128
        }
NEW
129
    }
×
130

131
    private static void ConfigureInstrumentation(
132
        IHostApplicationBuilder builder,
133
        WolverineBusOptions wolverineBusOptions,
134
        string connectionString
135
    )
136
    {
137
        if (!wolverineBusOptions.DisableTracing)
2✔
138
        {
139
            builder
2✔
140
                .Services.AddOpenTelemetry()
2✔
141
                .WithTracing(p =>
2✔
142
                {
2✔
143
                    p.AddSource("RabbitMQ.Client.*");
2✔
144
                });
2✔
145
        }
146
    }
2✔
147
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc