|
Introduction to Dapr for .NET Developers
Read on: my website / Read time: 10 minutes
|
|
|
|
The .NET Weekly is brought to you by:
Get every Dometrain Course at 40% off! Dometrain is an educational courses platform by Nick Chapsas. With 79 courses, 20 authors and more than 55.000 students, there is no better place to invest in your learning as a .NET engineer. Use code MILAN03 to get 40% off your first year of Dometrain Pro.
|
Archera is unique among cloud cost management products for a simple reason: they insure your cloud commitments. That means if you underutilize, say, an AWS Savings Plan or Microsoft Azure Consumption Commitment, they will write you an actual check to cover the difference.
They also allow you to achieve the cost savings of native cloud savings plans with a commitment as low as 30 days, instead of 1 to 3 years.
Check out their Azure offerings here.
|
|
|
|
Building distributed systems has never been more important—or more challenging. As .NET developers, we're constantly juggling service discovery, state management, messaging, resilience patterns, and various infrastructure SDKs. Our business logic gets buried under mountains of plumbing code, and we become tightly coupled to specific technologies.
What if there was a better way?
Enter Dapr (Distributed Application Runtime), an open-source project that handles the complex infrastructure challenges so you can focus on what matters most: your application's business logic.
In this article, we'll explore how Dapr transforms microservice development for .NET developers by:
- Abstracting away infrastructure-specific code behind consistent APIs
- Providing standardized building blocks for common distributed system patterns
- Enabling you to use the same code from local development to production
- Integrating seamlessly with .NET and ASP.NET Core applications
Whether you're building your first microservice or evolving a complex system, Dapr offers a simpler path forward. Let's explore how it works.
|
|
|
What is Dapr?
Dapr is a portable, event-driven runtime that simplifies building microservices. As a graduated project within the Cloud Native Computing Foundation (CNCF), Dapr has proven its value in production environments.
At its core, Dapr provides standardized building blocks that abstract away the complexity of common microservice patterns. Rather than wrestling with infrastructure-specific code, you can focus on your business logic while Dapr handles the rest.
Before Dapr, building a microservice architecture in .NET might require direct integration with multiple infrastructure components:
This approach tightly couples your application to specific technologies.
With Dapr, you gain flexibility through standardized APIs:
The underlying providers can be swapped without code changes - just by updating Dapr component configuration files.
|
|
|
The Sidecar Pattern: How Dapr Works
Dapr uses the sidecar architectural pattern, where it runs as a separate process alongside your application:
Your application communicates with the Dapr sidecar through HTTP or gRPC, and Dapr handles communication with infrastructure services. This separation brings several benefits:
- Language Agnostic: Dapr works with any programming language, including all .NET variants
- Cross-cutting Concerns: Security, observability, and resiliency are handled by Dapr, not your code
- Infrastructure Abstraction: Your application remains decoupled from specific technologies
- Simplified Development: Clean, maintainable code focused on business logic
- Production Ready: Built-in features that improve reliability in production environments
|
|
|
Building Blocks: Dapr's Core Capabilities
Dapr offers several building blocks that solve common microservice challenges. Each provides a standardized API that abstracts away infrastructure complexity:
- Service Invocation: Enables reliable service-to-service communication with automatic service discovery, load balancing, and retries.
- State Management: Provides a unified way to store and retrieve state with features like concurrency control and transactions.
- Pub/Sub: Implements asynchronous messaging between services, allowing for loosely-coupled, event-driven architectures.
- Bindings: Connects your applications to external systems, either for triggering your app from external events or invoking external services.
- Actors: Implements the virtual actor pattern, making it easy to build stateful microservices with encapsulated state and behavior.
- Secrets: Offers secure access to sensitive configuration like connection strings and API keys from various secret stores.
- Configuration: Centralizes application settings with support for dynamic updates across multiple services.
- Distributed Lock: Provides mutually exclusive access to shared resources in a distributed environment.
- Cryptography: Offers encryption and decryption operations while handling key management.
- Workflows: Enables you to define long running, persistent processes that span multiple microservices.
- Jobs: Allows you to schedule and orchestrate jobs (e.g., schedule batch processing jobs to run every business day)
- Conversation: Lets you supply prompts to converse with different large language models (LLMs). Includes prompt caching and PII obfuscation.
Here's an overview of Dapr's building blocks and the most popular services they interact with:
Let's explore the most commonly used building blocks in depth.
|
|
|
Service Invocation
The service invocation building block enables reliable service-to-service communication with automatic mTLS encryption, retries, and observability.
This solves several challenging microservice problems:
- Service Discovery: Finding where services are located
- Resilient Communication: Handling transient failures gracefully
- Load Balancing: Distributing requests across multiple instances
- Observability: Tracking requests across service boundaries
- Security: Encrypting traffic between services
Here's a simple example of invoking a service using Dapr's .NET SDK:
And the corresponding service handling the request:
What's happening here:
- The
checkout service calls InvokeMethodAsync using the DaprClient to send a request to the order service
- The Dapr sidecar for the checkout service receives this request
- The Dapr sidecar looks up the location of the order service
- The request is forwarded to the Dapr sidecar of the order service
- The order service's Dapr sidecar forwards the request to the order service
- The response follows the reverse path
This process provides automatic service discovery, encryption, retries, and distributed tracing without any additional code.
|
|
|
Publish & Subscribe
The publish and subscribe building block provides asynchronous messaging between services with at-least-once delivery guarantees. This pattern is essential for building resilient, loosely-coupled microservices that can:
- Process operations asynchronously without blocking the user
- Continue functioning when downstream services are unavailable
- Scale independently based on workload
Pub/Sub in Dapr follows this flow:
- A publisher service sends a message to a topic via the Dapr sidecar
- The publisher Dapr sidecar converts the message to the CloudEvent format and forwards it to the configured message broker
- Subscriber services receive the message through their Dapr sidecars
- The subscriber application processes the message
Dapr uses component configuration files to define the pub/sub message broker. Here's a typical Redis pub/sub component:
The key parts of this configuration are:
metadata.name : The component name (order-events ) that your application will reference when publishing/subscribing
spec.type : The type of component (pubsub.redis in this case)
spec.metadata : Configuration specific to the component type
This file should be placed in a components directory where Dapr can discover it. When running locally, this is typically ./components/ relative to your application.
What if you want to switch from Redis to RabbitMQ? You'd replace the spec.type with pubsub.rabbitmq and update the metadata section accordingly. This change doesn't require any code modifications in your application. Isn't this flexibility amazing?
Here's how to publish events using Dapr:
And here's how a subscriber would handle these events:
The key components:
- The publisher uses Dapr to send events to a topic
- Dapr handles the interaction with the message broker (Kafka, Redis, etc.)
- The subscriber decorates endpoints with
[Topic] attributes
- Dapr delivers the messages to the appropriate subscribers
Note that the name defined in the component file (order-events in our example) must match the first parameter used in PublishEventAsync("order-events", ...) and [Topic("order-events", ...)] . If these names don't match exactly, messages won't flow correctly between services.
|
|
|
Dapr and .NET Aspire: Better Together
Dapr works seamlessly with .NET Aspire, Microsoft's new cloud-ready stack for building distributed applications. While Aspire focuses on .NET-specific application orchestration, Dapr provides language-agnostic building blocks.
Here's how to integrate Dapr with a .NET Aspire application:
Note that I'm using the CommunityToolkit.Aspire.Hosting.Dapr package, which is the official Dapr integration for .NET Aspire. The Aspire.Hosting.Dapr library is now deprecated.
Here's an example of how a message flow might look in the Aspire dashboard:
|
|
|
Learning with Dapr University
If you're looking for a structured way to learn Dapr, I highly recommend checking out Dapr University. You can watch the lessons completely for free.
As someone who started with limited Dapr experience, I found the "Dapr 101" course particularly valuable. It provides hands-on exercises for State Management, Service Invocation, and Pub/Sub—exactly what you need to get started quickly.
|
|
|
Conclusion
Dapr simplifies microservice development for .NET developers by providing standardized building blocks that handle infrastructure complexity. With its sidecar pattern, Dapr lets you focus on business logic while it manages cross-cutting concerns. As you build distributed applications, consider how Dapr can help you:
- Accelerate development with ready-made patterns
- Build more resilient systems with fewer lines of code
- Avoid vendor lock-in through abstraction (building blocks)
- Improve production reliability with built-in best practices
Ready to dive deeper? Check out Dapr University for comprehensive courses and hands-on learning.
That's all for today. Hope this was helpful.
|
|
|
Whenever you're ready, there are 3 ways I can help you:
|
|
[NEW] Pragmatic REST APIs: You will learn how to build production-ready REST APIs using the latest ASP .NET Core features and best practices. Includes React client app. Production deployment to Azure with full CI/CD pipeline. Join 300+ engineers |
|
|
Pragmatic Clean Architecture: This comprehensive course will teach you the system I use to ship production-ready applications using Clean Architecture. Learn how to apply the best practices of modern software architecture. Join 3,900+ engineers |
|
|
|
You received this email because you subscribed to our list. You can unsubscribe at any time.
Update your profile | Dragiše Cvetkovića 2, Niš, - 18000
|
|
|
|
|