Messaging
Dapr.Messaging is the unified Dapr Publish/Subscribe messaging SDK for .NET. It brings all Dapr pub/sub functional modes—event publishing, streaming pull subscriptions, programmatic gRPC push subscriptions, and HTTP subscriptions—together into a single, modern package family.
Rather than fragmenting pub/sub across Dapr.Client and Dapr.AspNetCore, Dapr.Messaging provides a clean, cohesive programming model built on top of modern .NET fundamentals: Roslyn source generators for reflection-free dispatch, compile-time Roslyn analyzers, and the standard Microsoft.Extensions.Options pattern.
Unified package architecture
Dapr.Messaging is a meta-package that brings the runtime client (Dapr.Messaging.Runtime), core abstractions (Dapr.Messaging.Abstractions), source generators (Dapr.Messaging.Generators), and Roslyn analyzers (Dapr.Messaging.Analyzers) in a single package reference:
<ItemGroup>
<PackageReference Include="Dapr.Messaging" Version="..." />
</ItemGroup>
What changed
The Dapr .NET SDK originally distributed messaging capabilities across multiple packages: Dapr.Client provided basic publish and dynamic streaming pull methods, while Dapr.AspNetCore handled controller-based and minimal API push subscriptions via HTTP endpoints.
Dapr.Messaging unifies and modernizes this architecture:
- Unified publishing and subscribing: Publish events with
IDaprPublishSubscribeClient(including single events, raw byte streams, and bulk publishing) and author subscribers using a singleITopicHandler<TMessage>interface. - Three unified delivery modes: Subscriptions support
DeliveryMode.Streaming(application-initiated bidirectional gRPC stream with backpressure),DeliveryMode.Programmatic(sidecar-to-app gRPCAppCallbackpush), andDeliveryMode.Http(sidecar-to-app HTTP push via/dapr/subscribe), all configured through the same[DaprTopic]attribute. - Source generators eliminate reflection: The
Dapr.Messaging.Generatorssource generator inspects[DaprTopic]handlers at compile time and emits typed dispatchers, subscriber registries, and dependency injection wiring. No runtime reflection or runtime code generation is performed on the invocation path. - AOT and trimming considerations: Handler discovery and dispatch registration are generated at compile time, but the current generated subscriber dispatchers use runtime
System.Text.Jsonmetadata. Native AOT and trimming scenarios require explicit validation with the target SDK version. - Roslyn analyzers and diagnostics: The SDK includes compile-time analyzers (
DAPR1610–DAPR1617) that catch misconfigurations directly in your IDE as you write code:DAPR1610(Error): Conflicting delivery modes on the same topic.DAPR1611(Error):[DaprTopic]class not implementingITopicHandler<TMessage>.DAPR1612(Warning): Unregistered message type in Native AOT compilation.DAPR1613(Warning): Missingapp.MapDaprMessaging()for programmatic subscriptions (with CodeFix).DAPR1614(Warning): Direct invocation of internalDaprMessagingRegistration.DAPR1615(Warning): Endpoint mapping present without matching topic subscribers.DAPR1616(Warning):[DaprTopic]feature enabled without companion properties.DAPR1617(Warning): Ignored[DaprTopic]properties for the selected delivery mode or feature.
- Standard options and simplified DI: Uses
IOptions<DaprMessagingOptions>and a singleservices.AddDaprMessaging()method that registers options, the publishing client, source-generated subscriber dispatchers, and required hosting services in a single atomic operation.
Comparison with legacy pub/sub approaches
| Capability | Legacy (Dapr.Client / Dapr.AspNetCore) | Modern (Dapr.Messaging) |
|---|---|---|
| Package structure | Split across Dapr.Client and Dapr.AspNetCore | Single unified meta-package Dapr.Messaging |
| Publishing client | DaprClient.PublishEventAsync | Dedicated IDaprPublishSubscribeClient / DaprPublishSubscribeClient |
| Bulk publishing | DaprClient.BulkPublishEventAsync | IDaprPublishSubscribeClient.BulkPublishEventAsync with typed BulkPublishEntry<T> |
| Subscriptions model | Controller attributes ([Topic]) or minimal API endpoints | Unified ITopicHandler<TMessage> handlers decorated with [DaprTopic] |
| Delivery modes | Separate implementations for streaming gRPC vs HTTP | Configurable via DeliveryMode (Streaming, Programmatic, Http) |
| Streaming pull subscriptions | Imperative client calls only | Both declarative [DaprTopic(Delivery = DeliveryMode.Streaming)] and imperative SubscribeAsync |
| Dispatch mechanism | Runtime reflection / MVC action invokers | Source-generated typed dispatchers (AddDaprMessaging) |
| Native AOT & Trimming | Not supported | Requires explicit validation |
| Compile-time analyzers | None | Built-in Roslyn analyzers and code fixes (DAPR16xx) |
| Configuration | Custom builder methods | Standard Microsoft.Extensions.Options pattern (DaprMessagingOptions) |
| CloudEvents support | Manual deserialization or controller bindings | Strongly-typed CloudEvent, CloudEvent<TData>, and TopicContext.CloudEvent |
Core concepts
- Tutorial: Dapr.Messaging by example: Seven runnable examples covering publishing, streaming, routing, bulk subscriptions, gRPC push, HTTP push, dynamic streaming, and their unit and integration testing patterns.
- Publish events how-to: Step-by-step guide to publishing JSON events, CloudEvents, raw payloads, and bulk message batches using
IDaprPublishSubscribeClient. - Subscribe to topics how-to: Step-by-step guide to authoring
ITopicHandler<TMessage>subscribers, choosing delivery modes with[DaprTopic], compile-time source generation, dynamic streaming subscriptions, and compiler diagnostics. - Configuration and usage guide: Lifetime management, DI options configuration, advanced features (bulk pub/sub, dead-letter topics, CEL routing), and AOT/trimming considerations.
Next steps
- Tutorial: Dapr.Messaging by example
- How-To: Publish events with IDaprPublishSubscribeClient
- How-To: Author subscriptions and handle topic messages
- Dapr Messaging configuration and usage reference
- Dapr Pub/Sub building block overview