Dapr .NET SDK

repository·master·Indexed 22 days ago

https://github.com/dapr/dotnet-sdk

The Dapr .NET SDK provides high-level abstractions for .NET developers to interact with the Dapr runtime, enabling features such as state management, pub/sub, actors, and workflows within ASP.NET and general .NET applications. It includes the 'Actor.Next' pattern for simplified actor implementation, typed actor state migration via upcasters, and support for Native AOT benchmarks in .NET 10.

Tokens
22.1K
Snippets
65
Records
102
Agent score
79%

What's inside dapr-dotnet-sdk

  1. Overview of the Dapr SDK for .NET

    master

    The Dapr SDK for .NET provides tools to integrate .NET applications with the Dapr runtime. It enables three primary capabilities:

    1. Dapr Client Interaction: Interact with Dapr services and building blocks through a dedicated client.
    2. ASP.NET Integration: Build routes and controllers within ASP.NET applications using Dapr-specific extensions.
    3. Virtual Actor Model: Implement the Virtual Actor design pattern using the Dapr Actor building block.

    The SDK is designed to run in various environments, including local development, containers, and distributed systems.

  2. Explore ASP.NET Dapr integration examples

    master

    The examples/AspNetCore directory contains several implementation patterns for integrating Dapr with ASP.NET Core applications. Use these samples to understand how to handle different communication styles and configuration requirements:

    • Routing Sample: Demonstrates how to run Dapr alongside ASP.NET Core routing.
    • Controller Sample: Shows how to use Dapr within standard ASP.NET Core controllers.
    • gRPC Sample: Demonstrates running Dapr with the ASP.NET gRPC integration.
    • Secret Store Configuration: Provides an example of configuring a Secret Store provider within ASP.NET Core.
  3. Explore Dapr Client examples

    master

    The Dapr .NET SDK provides several example implementations for core Dapr building blocks. You can use these examples to learn how to implement the following patterns in your .NET applications:

    • Service Invocation: How to call other services via Dapr.
    • State Management: How to save, retrieve, and manage application state.
    • Publish and Subscribe: How to publish events to topics and subscribe to them.
    • Configuration API: How to access remote configuration settings.
    • Distributed Lock: How to manage distributed locks across multiple instances.
  4. Implement document types using InterpretedStateMachineActor

    master

    Instead of creating a new actor class for every document type, use a single InterpretedStateMachineActor and deploy different InterpretedMachineDefinition objects at runtime.

    Key Components

    • InterpretedMachineDefinition: The data structure defining the state machine (states, transitions, guards, and effects).
    • InterpretedMachineVerifier: Validates that a definition is sound (no dead-ends or unreachable states) and that all referenced guards/effects exist in the ICapabilityRegistry.
    • InterpretedMachineDeployer: Uses the verifier to check a definition before storing it via DeployAsync.
    • ICapabilityRegistry: A registry where you map string names (like "StartSettlement") used in the data definition to actual compiled C# actions.

    This approach allows you to onboard new business logic by simply deploying new data configurations.

  5. How typed actor state migration works

    master

    Typed actor state migration allows actor code to always work with the most current state shape, even if the data persisted in the underlying store is in an older format. The Dapr SDK handles this by 'folding' older persisted shapes forward through a chain of registered upcasters.

    Migration Patterns

    • Hand-authored Upcasters: Used when state changes are complex (e.g., CartStateV1 -> CartStateV2 -> CartStateV3). The actor code only interacts with the latest version (e.g., CartStateV3) using standard methods like GetOrCreateAsync or TryGetAsync. It does not need to contain logic to branch on version numbers.
    • Additive-only Migration: If changes are purely additive, no manual upcasters are required. The SDK generator automatically emits the necessary 'hops' between versions.
    • Non-additive Migration: For breaking changes (like renaming fields), a hand-authored upcaster is required to map the old schema to the new one.
    • State Graduation: You can use a method (e.g., GraduateAsync) to write a value in its 'plain' (current) form. This allows the state to exit the migration envelope and be stored without the migration overhead.

    Legacy Imports and Healing

    When you post a legacy payload (e.g., a V1 or V2 type) via SetAsync, the SDK treats it as that specific legacy type. On the next read, the SDK folds that legacy type into the current version. The underlying store is 'healed' (updated to the latest version) when the actor performs a turn flush.

  6. Implement a Dapr Actor in .NET

    master

    To implement a Dapr Actor, you need three distinct components:

    1. Interface Project: Defines the actor contract (e.g., IDemoActor). This interface should be in a separate assembly so it can be shared by both the actor implementation and the clients.
    2. Actor Service Project: The ASP.NET Core web service that hosts the actor. The actor implementation must:
      • Derive from the base Actor class.
      • Implement the interfaces defined in the Interface Project.
      • Include a constructor that accepts an ActorService instance and an ActorId, passing them to the base Actor class.
    3. Actor Client Project: Implements the client logic that calls the actor's methods using the shared interface.
  7. How Interpreted Actors work in Dapr Actor.Next

    master

    In the Actor.Next model, Interpreted Actors allow for runtime-defined behavior using state-machine configuration documents rather than compile-time code.

    Key Concepts

    • InterpretedMachineDefinition: A document defining the state machine (states, transitions, guards, and effects).
    • InterpretedMachineVerifier: Validates the definition before rollout.
    • InterpretedMachineDeployer: Handles the storage and deployment of the definition.
    • InterpretedStateMachineActor: A single, compiled actor that executes the logic defined in the InterpretedMachineDefinition.
    • ICapabilityRegistry: Resolves named guards (e.g., CheckBattery) and effects (e.g., ActuateMotor) through vetted, compiled actions.
    • IDynamicActorClient: Allows a control plane to send commands to actors without a compile-time contract, using weakly typed invocation.

    State and Versioning

    Unlike standard typed actors, interpreted actors carry a dynamic state bag. Versioning a device type is achieved by versioning its definition document as data, rather than using traditional typed state-migration patterns.

  8. Architecture of the Aspire and Dapr Integration Demo

    master

    The demo utilizes a multi-project structure to illustrate distributed application patterns:

    • AppHost: The .NET Aspire orchestration project that coordinates the lifecycle and discovery of all services.
    • Frontend Application: An ASP.NET Core web application that initiates service invocation calls to backend services.
    • Backend Application: ASP.NET Core API services that implement business logic and respond to service invocation requests.

    By combining Aspire (for orchestration and observability) with Dapr (for distributed runtime capabilities like service invocation), developers can achieve simplified local development while maintaining production-ready distributed patterns.

  9. Concept: Dapr Distributed Lock API

    master
    The Distributed Lock API (introduced in Dapr 1.8) is used to prevent multiple processes from accessing the same resource simultaneously. In Dapr, locks are scoped to a specific App ID. This is particularly useful in event-driven consumer patterns where multiple instances of the same service (sharing the same App ID) might attempt to process the same piece of work at the same time.
  10. How strongly-typed vs loosely-typed actor invocation works

    master

    The Dapr .NET SDK offers three patterns for invoking actor methods:

    1. Strongly-typed (remoting): Provides type safety but may have different performance characteristics.
    2. Loosely-typed (non-remoting): Uses string-based method names, which is flexible but lacks compile-time safety.
    3. Generated Client (Middle Option): Uses .NET Source Generators to create a strongly-typed client implementation that uses loosely-typed method invocation under the hood. This provides the developer experience of strong typing with the performance benefits of the loosely-typed approach.
  11. Implement Dapr AppCallback for Service Invocation and Pub/Sub

    master

    To allow the Dapr runtime to invoke methods, register for pub/sub topics, and handle bindings in a gRPC service, your service class must inherit from AppCallback.AppCallbackBase.

    Key methods to override include:

    • OnInvoke(InvokeRequest request, ServerCallContext context): Implement this to support Dapr's service invocation.
    • ListTopicSubscriptions(Empty request, ServerCallContext context): Implement this to register your service's pub/sub topic subscriptions.
    • OnTopicEvent(TopicEventRequest request, ServerCallContext context): Implement this to handle incoming pub/sub topic events.
    public class BankingService : AppCallback.AppCallbackBase
    {
        public override async Task<InvokeResponse> OnInvoke(InvokeRequest request, ServerCallContext context)
        {
            // Handle service invocation
        }
    
        public override Task<ListTopicSubscriptionsResponse> ListTopicSubscriptions(Empty request, ServerCallContext context)
        {
            // Register pub/sub topics
        }
    
        public override async Task<TopicEventResponse> OnTopicEvent(TopicEventRequest request, ServerCallContext context)
        {
            // Handle pub/sub topic events
        }
    }