Skip to content

v7: Host the bus through dependency injection (AddObvs, IOptions, ILogger, hosted service) #84

Closed

Description

@christopherread

Today: a bus is built with a long fluent chain carrying five or six generic parameters (ServiceBus.Configure().WithRabbitMQEndpoints<TServiceMessage>().Named(..).ConnectToBroker(..).SerializedAsJson().AsClientAndServer().Create()). The order matters, and mistakes produce generic-constraint compiler errors that are hard to act on. There is no integration with Microsoft.Extensions.*.

Proposal: services.AddObvs(...) with:

  • per-service options bound from IConfiguration, using IOptions validation on start;
  • ILogger throughout;
  • an IHostedService that starts and stops the bus;
  • IServiceBus and IServiceBusClient resolvable from DI.

Lifetime: the bus stays one shared instance, now enforced by DI.

  • IServiceBus and IServiceBusClient forward to one singleton registration, never two buses.
  • The container owns it: the hosted service starts it before the app takes traffic, stops it while letting in-flight handlers finish, and the container disposes it. App code no longer disposes the bus.
  • Handlers are resolved in a DI scope per message; the bus never holds onto scoped services.
  • Repeated AddObvs calls add to one bus configuration, or fail with an actionable error.
  • Instance ID: a DI singleton is one per container, not per process, so test hosts and WebApplicationFactory can create several buses in one process. Each bus gets an instance ID (a GUID by default, overridable in options), used in broker-side names instead of the process ID. That avoids v6's collisions: duplicate RabbitMQ exclusive queue names, a shared Kafka consumer group that splits messages between buses, and duplicate ActiveMQ client IDs on .NET Framework.
  • Keyed buses (AddObvs("name", ...) with [FromKeyedServices]) for the rare app that needs more than one, and a lightweight ObvsBus.StartAsync builder for apps without a host.

Done when: a worker service can configure, start and stop a bus purely through AddObvs and appsettings.json, with no fluent chain, and two hosts in one test process each run their own bus against the same broker without collisions.

Design: https://github.com/christopherread/Obvs/blob/master/docs/v7-design.md#1-host-the-bus-through-dependency-injection

Activity

  1. added this to the v7 milestone on Oct 25, 2026
  2. christopherread commented on Oct 26, 2026

    @christopherread
    OwnerAuthor

    Status on the v7 branch.

    Merged

    The "done when" is essentially met: a worker can configure, start and stop a bus purely through AddObvs and appsettings.json, and two hosts in one test process run their own buses against the same broker.

    Left

  3. added a commit that references this issue on Oct 27, 2026
  4. christopherread commented on Oct 27, 2026

    @christopherread
    OwnerAuthor

    Done in #107 (AddObvs, the hosted service and ILogger), #112, #118, #119, #121 and #123 (each transport's options from configuration), and #146 (ObvsBus.StartAsync for apps without a host, and logging transport errors). Merged into v7.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions