featured image

Integrating Dapr with DotNet Semantic Kernel Process Framework on Aspire

Learn how to integrate Dapr sidecars into your .NET Aspire projects with Microsoft’s Semantic Kernel Process Framework to run AI-powered workflows at cloud scale. This step-by-step guide covers installation, configuration and sample code to get resilient, actor-based processes running anywhere.

Prathamesh Dhande Prathamesh Dhande Sat Apr 26 2025 5 min read

In our previous blog, we explored an automated blog publishing workflow using the Process Framework’s LocalRuntime package. That approach worked well for local experimentation, but it cannot scale across multiple servers or containers. Today, we will walk through integrating Dapr sidecars into the same example so your workflows can grow seamlessly across any cloud environment.

What is Dapr?

Dapr (Distributed Application Runtime) is an open-source, language-agnostic sidecar that exposes a set of standardized HTTP and gRPC APIs for common distributed-systems concerns:

  • Service invocation
  • State management
  • Publish/subscribe messaging
  • Resource bindings
  • Secret management
  • Actors

Its pluggable component model (for Redis, Kafka, Azure Cosmos DB, and more) lets you swap underlying infrastructure without changing your code. Dapr also handles retries, health checks, and provides observability out of the box, letting you focus on business logic.

Why Use Dapr with the Process Framework?

When your workflows need to run across a cluster of machines or scale dynamically, Dapr is a natural choice as a runtime for the Process Framework. Here are some of the key benefits:

  • Standardized APIs for state, invocation, and pub/sub let you focus on workflow logic.
  • Pluggable components mean you can switch backing stores or messaging systems without code changes.
  • Built‑in resilience through retries and health checks.
  • Cloud‑agnostic scaling via sidecars that run unchanged locally, on Kubernetes, or on any VM.

These features make Dapr a powerful runtime for AI‑powered workflows that must run at scale.

Actors in Dapr?

Under the hood, Dapr uses the actor model to host each process step. Actors are single‑threaded, message‑driven objects. When an actor receives a message, it processes it then may send messages to other actors. The Dapr runtime handles scheduling and routing so many actors can run concurrently without extra configuration.

Learn more about Aspire on our Getting Started Guide.

Prerequisites

Make sure you have the following installed:

Installing Required Packages

In your ASP.NET MVC project, add the following NuGet packages:

# Dapr integration
dotnet add package Dapr.AspNetCore
dotnet add package Dapr.Actors.AspNetCore

# Process Framework Dapr runtime
dotnet remove package Microsoft.SemanticKernel.Process.Runtime.Local
dotnet add package Microsoft.SemanticKernel.Process.Runtime.Dapr --version 1.47.0-alpha

Uninstall LocalRuntime packages for the Process Framework before installing the Dapr runtime package. The code you wrote for the Process Framework does not need to change.

In Your Aspire AppHost Project, Add the following NuGet Packages:

dotnet add package CommunityToolkit.Aspire.Hosting.Dapr --version 9.4.1-beta.277

Configuring Aspire and Dapr in Your AppHost

In your Aspire.AppHost project, reference the ProcessFramework project and enable the Dapr sidecar:

// Program.cs in Aspire.AppHost
var builder = DistributedApplication.CreateBuilder(args);

var daprtutorial = builder.AddProject<Projects.DaprTutorial>("daprtutorial")
                          .WithDaprSidecar();
                          
builder.Build().Run();

The WithDaprSidecar method ensures that a Dapr sidecar is started alongside your process host. All inter-service communication goes through the Dapr sidecars.

This will create a setup that looks like this: Dapr Sidecar Architecture

Initializing Dapr Locally

  1. Install the Dapr CLI on your system.
  2. Initialize Dapr on your local machine:
    dapr init
    
    This command pulls Docker images for the Dapr runtime and Redis (used by default for state and pub/sub) and starts them in containers.

Modifications in Code

Adding Dapr to ASP.NET Core

In your MVC Project, add the following methods in Program.cs to enable Dapr support, which will help the Process Framework run the workflow:

//Program.cs
using Microsoft.SemanticKernel;
using ProcessFramework.Steps;

var builder = WebApplication.CreateBuilder(args);
builder.AddServiceDefaults();

builder.Services.AddControllersWithViews();
// Add the Dapr Support to the MVC
builder.Services.AddMvc().AddDapr();
// Adding the Process Steps into the Dapr Actors

builder.Services.AddActors(static configure =>
{
    configure.AddProcessActors();
});

var app = builder.Build();
app.MapDefaultEndpoints();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
}
app.UseStaticFiles();
app.UseRouting();
app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");
app.MapControllers();

// Mapping the Actor
app.MapActorsHandlers();
app.Run();

Here we added the AddDapr() extension for MVC and registered our process steps (which inherit from Dapr’s Actor base class) via AddProcessActors(). Mapping actors with MapActorsHandlers() exposes the HTTP or gRPC endpoints that Dapr sidecars call.

Creating a Controller to Trigger the Workflow

In your HomeController, add an action that starts the blog publishing process:

//HomeController.cs
public class HomeController : Controller
{
    private readonly ILogger<HomeController> _logger;
    private Kernel _kernel;
    private readonly IConfiguration _config;
    public HomeController(ILogger<HomeController> logger, Kernel kernel, IConfiguration config)
    {
        _config = config;
        _kernel = kernel;
        _logger = logger;
    }
    public IActionResult Index()
    {
        return View();
    }
    [HttpGet, Route("api/runprocess/{processid}")]
    public async Task<IActionResult> RunProcessAsync(string processid)
    {
        DocumentationProcess docprocess = new DocumentationProcess(_config);
        KernelProcess process = docprocess.BuildSimpleProcess();
        DaprKernelProcessContext context = await process.StartAsync(new() { Data = "productname" + processid, Id = "start" }, processid);
        return Ok("Process Completed");
    }
}

In the controller above, we’ve added an action method named RunProcessAsync which runs the process asynchronously, allowing it to handle requests from multiple users concurrently.

Running the Aspire Project

Run the AppHost Project:

Dapr Sidecar Resource

Aspire will start a command‑line host alongside your web project, each with its own Dapr sidecar.

Observing Workflow Execution

While the workflow runs, Aspire’s logs illustrate calls to the Dapr sidecar for saving actor state and publishing messages. You will see logs similar to the following:

Workflow Execution By default, Dapr uses Redis to store state, but you can switch to Kafka or Cosmos DB in your components configuration without changing any C# code.

Output

Output

In the image, you can see the output generated when the steps execute. We used Dapr Pub/Sub to retrieve data from the steps because we can’t access it directly while they run. However, relying on Pub/Sub to present data to users isn’t ideal. For real-time visualization, using WebSockets or SignalR would be a better choice.

Next Steps

In our next blog post, we will cover how to deploy this solution to cloud environment using Dapr sidecars and demonstrate how to use real‑time communication channels to stream process step results to users.

Conclusion

In this blog, we’ve enhanced our Process Framework implementation by using Dapr instead of LocalRuntime. This approach brings powerful distributed capabilities, making our workflow solutions scalable and resilient. By leveraging Dapr’s actor model, we can run steps independently across multiple instances while maintaining state consistency. The integration with Microsoft Aspire simplifies development and deployment, providing excellent observability into our distributed processes.

Next
Understanding Selection and Termination Strategy functions in .NET Semantic Kernel Agent Framework