DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Building Cross-Platform Apps: A Complete Guide With .NET Core
  • ActiveMQ JMS (Java Messaging Service) vs. Data Streaming Kafka With Camel Code Sample
  • The Role of Retrieval Augmented Generation (RAG) in Development of AI-Infused Enterprise Applications
  • How the Go Runtime Preempts Goroutines for Efficient Concurrency

Trending

  • Testing SingleStore's MCP Server
  • Unlocking the Benefits of a Private API in AWS API Gateway
  • Unlocking the Potential of Apache Iceberg: A Comprehensive Analysis
  • Unlocking AI Coding Assistants Part 3: Generating Diagrams, Open API Specs, And Test Data
  1. DZone
  2. Software Design and Architecture
  3. Integration
  4. Open Source .NET Aspire and Dapr: What Are They and How Do They Complement Each Other For Distributed Apps?

Open Source .NET Aspire and Dapr: What Are They and How Do They Complement Each Other For Distributed Apps?

This article covers both .NET Aspire and Dapr, the problems they solve, their differences, and why .NET developers should use them together.

By 
Marc Duiker user avatar
Marc Duiker
·
Sep. 20, 24 · Tutorial
Likes (3)
Comment
Save
Tweet
Share
3.8K Views

Join the DZone community and get the full member experience.

Join For Free

Over the last weeks, I've seen many questions from the .NET community on how .NET Aspire compares to Dapr, the Distributed Application Runtime. Some say the features appear to be very similar and think Aspire is a replacement for Dapr (which it isn’t). The TL;DR is: .NET Aspire is a set of tools for local development, while Dapr is a runtime offering building block APIs and is used during local development and running in production. This article covers both .NET Aspire and Dapr, the problems they solve, their differences, and why .NET developers should use them together when building distributed applications that can run on any cloud. 

.NET Aspire graphic

What Problem Does .NET Aspire Solve?

.NET Aspire was created to solve a problem that many distributed application developers face: running and debugging multiple cloud native apps locally. .NET developers can now use a language they understand well, C#, to configure their microservices and infrastructure dependencies, such as state stores and message brokers. Developers can run and debug their .NET applications using Visual Studio or VS Code with the C# Dev Kit extension.

How Does .NET Aspire Work?

To run and debug multiple .NET applications locally, developers need a way to configure all the applications and related infrastructure dependencies. With .NET Aspire, this is done with an App Host project that orchestrates all the resources.

.NET Aspire orchestration overview

Source: .NET Aspire orchestration overview

This is the csproj file of an App Host project for a .NET Aspire + Dapr solution that consists of two Dapr applications that communicate asynchronously via a message broker:

XML
 
<Project Sdk="Microsoft.NET.Sdk">

   <PropertyGroup>
     <OutputType>Exe</OutputType>
     <TargetFramework>net8.0</TargetFramework>
     <ImplicitUsings>enable</ImplicitUsings>
     <Nullable>enable</Nullable>
     <IsAspireHost>true</IsAspireHost>
   </PropertyGroup>
 
  <ItemGroup>
     <PackageReference Include="Aspire.Hosting.AppHost" Version="8.0.1" />
     <PackageReference Include="Aspire.Hosting.Dapr" Version="8.0.1" />
  </ItemGroup>

  <ItemGroup>
     <ProjectReference Include="..\checkout\DaprAspirePubsub.Checkout.csproj" />
     <ProjectReference Include="..\order-processor\DaprAspirePubsub.OrderProcessor.csproj" />
  </ItemGroup>

</Project>


This is the Program.cs file of the App Host project:

C#
 
var builder = DistributedApplication.CreateBuilder(args);
var pubsubComponent = builder.AddDaprPubSub("orderpubsub");

builder.AddProject("checkout")
       .WithDaprSidecar()
       .WithReference(pubsubComponent);

builder.AddProject("order-processor")
       .WithDaprSidecar()
       .WithReference(pubsubComponent);

builder.Build().Run();


Once the App Model is defined in the App Host project, and this project is set as the start-up project, the entire solution can be run and debugged as usual. The App Host project is started as a separate process and orchestrates which other resources will be started.

.NET Aspire Terminology

  • App model: A collection of resources that defines the distributed application
  • App host: The .NET project that orchestrates the app model; by convention, these projects use the AppHost suffix in their name
  • Resource: A part of a distributed application; this can be a .NET project, a container, an executable, a cloud resource, or an external service
  • Reference: A connection between resources, such as a dependency to a state store, or a reference to another .NET project
  • Integration (previously Component): A .NET library that delivers a specific integration with an infrastructure resource, such as a Kafka message broker or a Cosmos DB database; Developers can add these components as NuGet packages to the AppHost or application projects. Components typically register a specific client object in the dependency injection container, so developers can use that client in their application code. Both .NET Aspire and Dapr use the term components, but they are very different in their implementation.

Example for Adding the .NET Aspire Cosmos DB Integration

1. First add the Cosmos DB integration to the project that requires a connection with Cosmos DB:

dotnet add package Aspire.Microsoft.Azure.Cosmos

2. The component can now be registered in the Program.cs file of in the project:

builder.AddAzureCosmosClient("cosmosdb");

3. The CosmosDB client can now be used in the application code:

C#
 
public class ExampleService(CosmosClient client)
{
    // Use client...

}


For running and debugging the above example, a corresponding hosting package needs to be added to the AppHost.

4. Add the Cosmos DB hosting package:

dotnet add package Aspire.Hosting.Azure.CosmosDB

5. Register the Cosmos DB host in the AppHost project:

C#
 
var builder = DistributedApplication.CreateBuilder(args);
var cosmos = builder.AddAzureCosmosDB("cosmos");
var cosmosdb = cosmos.AddDatabase("cosmosdb");
var exampleProject = builder.AddProject()
                            .WithReference(cosmosdb);


Note that this configuration requires a Cosmos DB resource in Azure to run the code locally. For this specific resource, a local emulator is available that can be added with cosmosdb.RunAsEmulator();.

What Do You Need To Run .NET Aspire With Dapr?

  • .NET 8
  • The .NET Aspire workload
  • Visual Studio 22 17.10 or VS Code with the C# Dev Kit
  • A container runtime such as  Docker Desktop or Podman
  • Dapr CLI

What Is Dapr (Distributed Application Runtime)?

Dapr is a runtime that provides a set of APIs developers can use to build distributed applications quickly. These APIs are decoupled from the underlying infrastructure, which enables developers (or platform engineers) to switch between different infrastructure implementations without changing application source code.

Dapr runs in a separate process (sidecar) next to the application, and has built-in observability, resiliency, and security features, all configurable and with default settings. Since all communication between services takes place via Dapr, application developers do not need additional code or dependencies to apply these cross-cutting concerns.

Dapr from development to hosting

Source: How to give a presentation on Dapr and examples

What Problem Does Dapr Solve?

Dapr was created to streamline secure and reliable distributed application development, regardless of the programming language or cloud provider. Developers can use the suite of Dapr APIs via HTTP/gRPC, or via the many language SDKs, to build microservices quickly. Dapr is not only used during development, Dapr is also running in production, providing secure and reliable communication between services and resources on any cloud or on-premise.

Developers claim to save about 30% of development time when using Dapr. This is due to the built-in cross-cutting concerns, and the decoupling of the APIs and underlying infrastructure. Developers can use in-memory or container-based resources locally, and switch to cloud-based or on-premise resources by replacing Dapr component files (YAML) when moving to production. An example of a Dapr component file is provided in the next section.

How Does Dapr Work?

As mentioned before, Dapr runs in a separate process next to your application. For each application in your distributed application landscape, a Dapr sidecar is present.

During application development, the Dapr CLI with the Multi-App-run feature is used to run multiple Dapr applications at the same time and configure resources the applications depend on.

This is the multi-app run file for two Dapr applications that communicate asynchronously via a message broker:

YAML
 
version: 1
common:
  resourcesPath: resources
apps:
  - appID: order-processor
    appDirPath: ./order-processor/
    appPort: 7006
    command: ["dotnet", "run"]
  - appID: checkout-sdk
    appDirPath: ./checkout/
    command: ["dotnet", "run"]


The resourcesPath attribute points to a resources folder. This folder contains a Dapr component file (pubsub.yaml) that describes which specific Pub/Sub implementation Dapr will use:

YAML
 
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: orderpubsub
spec:
  type: pubsub.redis
  version: v1
  metadata:
  - name: redisHost
    value: localhost:6379
  - name: redisPassword
    value: ""


Once the multi-app run file and component files are in place, all Dapr apps can be run with the Dapr CLI: dapr run -f .

Dapr Terminology

  • App/Application: An application that a developer writes and runs
  • Building block: A Dapr API that provides a specific functionality, such as State Management, or Pub/Sub, that a developer can use when writing an application
  • Configuration: A Dapr setting or policy to change the behavior of Dapr applications or the global behavior of the Dapr control plane
  • Sidecar: A type of architecture that Dapr uses. Dapr runs in a separate process, the sidecar, next to your application
  • Component: An implementation of one of the Dapr APIs that delivers a specific integration with an infrastructure resource, such as a Kafka message broker or a Cosmos DB database. Dapr Components are configured via YAML files.

Example for Adding the Dapr Cosmos DB component

1. A YAML file (component file) for Azure Cosmos DB is added to the solution:

YAML
 
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: mystatestore
spec:
  type: state.azure.cosmosdb
  version: v1
  metadata:
  - name: url
    value:
  - name: masterKey
    value:
  - name: database
    value:
  - name: collection
    value:


Note that for production use, a secret store should be used instead of plain text values.

2. If the Dapr .NET SDK is used, add the Dapr.AspNetCore NuGet package to the project:

dotnet add package Dapr.AspNetCore

3. In the Program.cs file, the DaprClient can now be registered:

builder.Services.AddDaprClient();

4. The DaprClient can now be used in application code:

C#
 
public class ExampleService(DaprClient daprClient)
{
	await daprClient.SaveStateAsync("mystatestore", order.Id, order.ToString())
}


Note that there is no Cosmos DB specific client code used in the application. The application only uses the Dapr SDK, and even this is optional, since raw HTTP/gRPC calls can be made to the Dapr sidecar. The Dapr sidecar is responsible for communicating with the Cosmos DB resource.

What Do You Need To Run .NET Applications Using the Dapr CLI With Multi-App Run?

  • .NET Core 3.1 or .NET 5 or higher
  • A terminal
  • Any IDE that supports .NET
  • A container runtime such as  Docker Desktop or Podman
  • Dapr CLI

.NET Aspire and Dapr Similarities and Differences

The goal of .NET Aspire and Dapr is similar: make it easier and quicker for developers to build cloud native distributed applications. The way both projects are doing this is very different, and the scope of Dapr is much wider. .NET Aspire is focused on the local development experience, while Dapr covers both local development and running distributed apps in production. Let’s take a look at some feature similarities and differences in the next section. Note that both projects are extensive and this is not a comparison of all the features. It’s also not completely fair to compare the two, since .NET Aspire is a "local dev tool" and Dapr is a runtime. Use this information to understand how you can combine the two solutions to speed up your distributed application development.

Feature Similarities

Some features that appear very similar between .NET Aspire and Dapr are as follows:

Service Discovery

.NET Aspire provides local service discovery via a configuration-based endpoint resolver in the AppHost project by adding Aspire references to the .NET projects. When deploying to Kubernetes, a Service resource definition YAML file needs to be created, and the AppHost code requires to be updated to use the DNS SRV service endpoint resolver.

Dapr provides service discovery via a name resolution component, and unique IDs for the Dapr sidecars. When running locally, name resolution can be configured to use either mDNS or SQLite. In production, this is handled by Kubernetes automatically, or HashiCorp Consul can be configured when running on VMs.

Observability

.NET Aspire uses the .NET OpenTelemetry SDK to enable observability. Dapr uses the OpenTelemetry protocol as well (the Zipkin protocol can also be configured).

Resiliency

Both .NET Aspire and Dapr enable development of resilient applications, but the implementation is quite different. With NET Aspire (or any .NET project), resiliency for HTTP communication can be added via the Microsoft.Extensions.Http.Resilience NuGet package. Some .NET Aspire components also allow resiliency configuration, but those are Aspire component specific and set in code. The application itself is responsible for resilient connections with services or resources it communicates with.

Dapr has built-in resiliency, and the Dapr sidecar is responsible for resilient connections between services and resources. This means that you don't need extra packages or application code. Dapr comes with default settings for retries and circuit breakers and can be customized with YAML files. These resiliency policies can be scoped to specific services or resources, so fine-grained control is possible.

The Concept of Components/Integrations

Although the implementation and scope is completely different, the concept of components to specify the dependency to other resources is similar. With .NET Aspire, NuGet packages are used to inject resource-specific libraries that enable the applications to use certain resources.

With Dapr, developers use component YAML files to configure the underlying resources. The .NET Aspire components, however, do not share a common API as Dapr components do. So, with .NET Aspire, developers still need to use resource-specific SDKs and cannot swap components without changing application source code.

Feature Differences

Although there are some similarities between .NET Aspire and Dapr, they are very different solutions for building distributed applications quicker.

APIs

The most significant difference is that Dapr offers many building block APIs, which are decoupled from the underlying infrastructure. Developers use these APIs to build distributed applications quickly. This is something that .NET Aspire does not offer. With Aspire, you still need to use resource-specific SDKs in your source code when interacting with state stores, secret stores, message brokers etc.

Languages

Another significant difference is that since Dapr runs in a sidecar, and offers the APIs via an HTTP/gRPC interface, Dapr can be used with any programming language. .NET Aspire is really focused on .NET, as the name implies. It is possible to run .NET Aspire apps that include a front-end with React/Vue/Angular, but it always requires an AppHost .NET project.

Security Policies

Dapr has built-in security policies that can be customized via YAML files. The security policies allow developers to configure which applications have access to other applications or resources. These policies can be applied globally or scoped to specific resources.

.NET Aspire does not provide security policies to control service-to-service or service-to-resource communication.

Application Deployment

.NET Aspire offers integrated application deployment options via Visual Studio (right-click publish), or the Azure Developer CLI (azd). Currently, these options are focused on Azure, limited to Azure Container Apps, but other environments will be added over time, according to the docs. The deployment process involves the creation of manifest files (JSON) that describe the resources. Kubernetes deployments are also supported, but this requires mapping the .NET Aspire JSON manifest files to Kubernetes YAML files.

Dapr does not provide integrated application deployment options with any IDE. The Dapr control plane can be installed on Kubernetes via the Dapr CLI, but this does not include application deployment. Since Dapr applications are typically run on Kubernetes, container images are created with tools as Docker, Skaffold, or Tilt. Deployment of the containers is done via CI/CD tooling to either a managed Kubernetes environment in the cloud, or a Kubernetes cluster on premise. Dapr applications can also be deployed to Azure Container Apps using the Azure CLI.

Dashboard

Although both .NET Aspire and Dapr offer dashboards, the Aspire dashboard to view resources, console logs, traces, and metrics is more comprehensive compared to the Dapr dashboard which is limited to Dapr resources only.

The Aspire dashboard also is sleek compared to the Dapr dashboard, which was designed by a back-end developer.

There are other Dapr tools available, such as Diagrid Conductor Free, that offers extensive features including cluster management, application monitoring and alerting with in-depth metrics, and an advisor for best practices, security, and reliability.

Better Together

If you’re developing distributed apps in .NET, Aspire offers a really smooth experience for local development. You don’t have to choose between .NET Aspire or Dapr to build distributed applications quicker. These two solutions complement each other, and save you even more development time.

Why are they better together? Because .NET Aspire gives you easy composability of your apps using C# and effortless debugging, while Dapr provides the building block APIs and built-in cross-cutting concerns such as security and resiliency. The Dapr APIs allow you to quickly build and run applications without depending on specific infrastructure SDKs in your code. This enables you to switch components between environments (local vs production), and even between different cloud providers, without requiring any changes to application code. The policies for security and resiliency you get with Dapr help you to develop production grade distributed applications.

More Info

Watch the .NET Aspire introduction video by David Fowler and Phillip Hoff at one of the Dapr Community Calls.

Cosmos DB Message broker applications Distributed development .NET

Published at DZone with permission of Marc Duiker. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Building Cross-Platform Apps: A Complete Guide With .NET Core
  • ActiveMQ JMS (Java Messaging Service) vs. Data Streaming Kafka With Camel Code Sample
  • The Role of Retrieval Augmented Generation (RAG) in Development of AI-Infused Enterprise Applications
  • How the Go Runtime Preempts Goroutines for Efficient Concurrency

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!