# Concepts (/integrations/aspire/concepts)



The KubeMQ .NET Aspire integration follows the standard Aspire **two-package model**: one package provisions the broker in your orchestrator, the other configures a typed client in each consuming service. Understanding how the two halves connect — and what the client wires up for you — makes the rest of the docs fall into place. This page is the mental model; the API tables live in the [Reference](/integrations/aspire/reference/hosting-api), and the runnable code lives on the capability pages.

## The two packages [#the-two-packages]

Aspire apps are split into an **AppHost** (the orchestrator that declares resources) and one or more **service** projects (your actual apps). KubeMQ mirrors that split with two packages.

| Package                 | Project | Responsibility                                                            |
| ----------------------- | ------- | ------------------------------------------------------------------------- |
| `KubeMQ.Aspire.Hosting` | AppHost | Provision a KubeMQ broker **container** as a resource                     |
| `KubeMQ.Aspire.Client`  | Service | Configure `IKubeMQClient` with health checks, OpenTelemetry, and keyed DI |

The hosting package never touches your application code; the client package never provisions anything. They meet at exactly one point: the **connection string** the AppHost injects and the client reads back.

<Mermaid
  chart="flowchart LR
    subgraph AppHost[&#x22;AppHost — KubeMQ.Aspire.Hosting&#x22;]
        Add[&#x22;AddKubeMQ('messaging')&#x22;]
        Add --> Cont[&#x22;KubeMQ container<br/>europe-docker.pkg.dev/kubemq/images/kubemq:2.5.0&#x22;]
    end
    Add -->|&#x22;connection string<br/>(host:port)&#x22;| Svc
    subgraph Service[&#x22;Service — KubeMQ.Aspire.Client&#x22;]
        Svc[&#x22;AddKubeMQClient('messaging')&#x22;]
        Svc --> Client[&#x22;IKubeMQClient&#x22;]
        Svc -.-> HC[&#x22;Health checks<br/>(ready / live)&#x22;]
        Svc -.-> OTel[&#x22;OpenTelemetry<br/>(KubeMQ.Sdk)&#x22;]
    end
    Client -->|&#x22;gRPC :50000&#x22;| Cont"
/>

*The AppHost provisions the broker container and injects its address; the client reads that address, builds an `IKubeMQClient`, and registers health checks and telemetry as side outputs into the Aspire pipeline.*

## Container provisioning [#container-provisioning]

`AddKubeMQ("messaging")` in the AppHost registers a `KubeMQServerResource` — a container resource backed by the `europe-docker.pkg.dev/kubemq/images/kubemq:2.5.0` image. It maps three endpoints (gRPC `50000`, REST `9090`, Dashboard `8080`) and uses a **persistent** container lifetime, so the broker — and any volume bound with `WithDataVolume()` — survives AppHost restarts between debug sessions. The license key is supplied as a secret parameter through `WithLicenseKey()`, which sets `KUBEMQ_TOKEN` on the container. See the [Hosting API](/integrations/aspire/reference/hosting-api) for the full method and endpoint tables.

## Connection-string injection [#connection-string-injection]

The KubeMQ resource implements `IResourceWithConnectionString`, expressing its address as a plain `host:port` string built from the gRPC endpoint (no scheme prefix). When a service declares `WithReference(messaging)`, Aspire injects that string into the service's configuration under the resource name. On the service side, `AddKubeMQClient("messaging")` resolves it back by the same name — so **no host or port is ever hard-coded**. The connection name is the contract: it must match on both sides. The parser's exact rules (bracketed IPv6, rejected schemes, port range) are in the [Configuration reference](/integrations/aspire/reference/configuration).

## Keyed DI for multiple brokers [#keyed-di-for-multiple-brokers]

`AddKubeMQClient` registers a single, non-keyed `IKubeMQClient` and may be called only once per service. When a service must reach more than one broker, switch to `AddKeyedKubeMQClient(name)` — once per broker — and inject each client by key with `[FromKeyedServices(name)]`. The key doubles as the connection name, so `AddKeyedKubeMQClient("orders")` binds its settings from `Aspire:KubeMQ:Client:orders`. Because the SDK's own DI helper does not support keyed registration, the keyed path constructs the client directly and manages its lifecycle with a hosted service. The full walkthrough is in [Multiple KubeMQ Instances](/integrations/aspire/how-to/keyed-multi-instance).

## Health checks and OpenTelemetry [#health-checks-and-opentelemetry]

The client is not just a connection — it brings observability with it. By default `AddKubeMQClient` registers:

* **Two health checks** — a readiness check (`ready` tag) that pings the broker when the connection is `Ready`, and a liveness check (`live` tag) that reports process health from the connection state alone. They line up with the Aspire `ServiceDefaults` `/health` and `/alive` endpoints and with Kubernetes probes.
* **OpenTelemetry tracing and metrics** — the SDK's `KubeMQ.Sdk` activity source and meter, enrolled into the host's OpenTelemetry pipeline so KubeMQ spans and metrics appear in the Aspire dashboard alongside ASP.NET Core and runtime instrumentation.

Each piece can be disabled independently through `KubeMQClientSettings` (`DisableHealthChecks`, `DisableTracing`, `DisableMetrics`). The state-to-status mapping and the readiness ping internals are covered in [Health Checks and OpenTelemetry](/integrations/aspire/how-to/health-checks-observability).

## What the integration does not do [#what-the-integration-does-not-do]

The Aspire integration is a **wiring layer**, not a messaging API. Once `IKubeMQClient` is injected you use the native [KubeMQ.SDK.CSharp](https://www.nuget.org/packages/KubeMQ.SDK.CSharp) Events, Queues, Commands, and Queries APIs directly — the integration only handles provisioning, connection-string resolution, health checks, and telemetry. The messaging patterns themselves are documented on the [core KubeMQ docs](/deploy) and reframed for Aspire on the capability pages.

## Next steps [#next-steps]

<Cards>
  <Card title="Getting Started" href="/integrations/aspire/tutorials/getting-started" description="Provision a broker, reference it from a service, and send your first message." />

  <Card title="Pub/Sub and Events Store" href="/integrations/aspire/how-to/events" description="Publish, subscribe, and replay persisted events through the injected client." />

  <Card title="Hosting API" href="/integrations/aspire/reference/hosting-api" description="AddKubeMQ, builder methods, the container resource, and endpoints." />
</Cards>
