The .NET Stacks #39: 🔥 Is Dapr worth the hype?

This week, is Dapr for real?

Dave Brock
Dave Brock

Buckle up! It’s been a busy few weeks. With Ignite this week, things aren’t slowing down anytime soon. I’ve got you covered. Let’s get to it.

  • One big thing: Is Dapr worth the hype?
  • The little things: Blazor Desktop, .NET 5 on Azure Functions, ASP.NET Core health checks
  • Last week in the .NET world

One big thing: Is Dapr worth the hype?

I mentioned Dapr in passing last week, but its release competed with the release of .NET 6 Preview 1. I’ve been spending the last week trying to understand what exactly it is, and the Dapr for .NET Developers e-book has been mostly helpful. With Ignite kicking off on Tuesday, you’re going to start hearing a lot more about it. (If you don’t work with microservices, feel free to scroll to the next section.)

Dapr is a runtime for your microservice environment—in .NET terms, you could call it a “BCL for the cloud.” It provides abstractions for you to work with the complexities of distributed applications. Dapr calls these pluggable components. Think about all the buckets your distributed systems have: authentication/authorization, pub/sub messaging, state management, invoking services, observability, secrets management, and so on. Your services can call these pluggable components directly, and Dapr deals with calling all these dependencies on your behalf. For example, to call Redis you call the Dapr state management API. You can call Dapr from its native REST or gRPC APIs and also language-specific SDKs. I love the idea of calling pub/sub over HTTP and not haggling with specific message broker implementations.

Dapr uses a sidecar architecture, enabling it to run in a separate memory process. Dapr says this provides isolation—Dapr can connect to a service but isn’t dependent on it. Each service can then have its own runtime environment. It can run in your existing environment, the edge, and Kubernetes (it’s built for containerized environments). While shepherded for Microsoft, it’s pretty agnostic and isn’t only built for Azure (but that might be lost in the Microsoft messaging). With Dapr, services communicate through encrypted channels, service calls are automatically retried when transient errors occur, and automatic service discovery reduces the amount of configuration needed for services to find each other.

While Dapr is service mesh-like, it is more concerned with handling distributed application features and is not dedicated network infrastructure. Yes, Dapr is a proxy. But if you’re in the cloud, breaking news: you’re using proxies whether you like it or not.

Dapr promises to handle the tricky parts for you through a consistent interface. Sure, you can do retries, proxies, network communication, and pub/sub on your own, but it’s probably a lot of duct tape and glue if you have a reasonably complex system.

With the release of Dapr v1.0, it’s production-ready. Will this latest “distributed systems made easy” offering solve all your problems? Of course not. Dapr uses the calls over the highly-performant gRPC, but that’s a lot of network calls. The line To increase performance, developers can call the Dapr building blocks with gRPC needs some unpacking. The team discusses low latency but will REST be enough for all its chatter? Are you ready to hand your keys to yet another layer of abstraction? Would you be happy with a cloud within your cloud? Does your app have scale and complexity requirements that make this a necessity? Are you worried about leaky abstractions?

There’s a lot going on here, and I plan to explore more. If you wanted to learn more about Dapr, I hope this gets the ball rolling for you.

The little things: Blazor Desktop, .NET 5 on Azure Functions, health checks

With the release of .NET 6 Preview 1 last week, one of the most interesting takeaways was the mention of Blazor desktop apps. (It wasn’t part of Preview 1, but a preview of what’s to come for .NET 6.) As if we didn’t have enough desktop dev options to worry about—WPF, UWP, WinUI, .NET MAUI, WinForms, and so on–where does this even fit?

Here’s what Richard Lander wrote:

Blazor has become a very popular way to write .NET web apps. We first supported Blazor on the server, then in the browser with WebAssembly, and now we’re extending it again, to enable you to write Blazor desktop apps. Blazor desktop enables you to create hybrid client apps, which combine web and native UI together in a native client application. It is primarily targeted at web developers that want provide rich client and offline experiences for their users.

Initially, Blazor Desktop will not utilize WebAssembly. Built on top of the .NET MAUI platform coming with .NET 6, it’ll use that stack to use native containers and controls. You can choose to use Blazor for your entire desktop app or only for targeted functionality—in the blog post, Lander mentions a Blazor-driven user profile page integrated with an otherwise native WPF app.

It appears this will work similarly to Electron. There will be a WebView control responsible for rendering content from an embedded Blazor web server, which can serve both Blazor components and other static assets. If you’re hoping to see one unifying platform for native development, I wouldn’t hold your breath—but if you like working with Blazor (especially if you’re apprehensive of XAML), it’ll be worth a try.

In this week’s shameless plug, I wrote about using Azure Functions with .NET 5. A new out-of-process model is in preview. Here’s the story behind it:

Traditionally, .NET support on Azure Functions has been tied to the Azure Functions runtime. You couldn’t just expect to use the new .NET version in your Functions as soon as it was released. Because .NET 5 is not LTS, and Microsoft needs to support specific releases for extended periods, they can’t upgrade the host to a non-LTS version because it isn’t supported for very long (15 months from the November 2020 release). This doesn’t mean you can’t use .NET 5 with your Azure Functions. To do so, the team has rolled out a new out-of-process model that runs a worker process along the runtime. Because it runs in a separate process, you don’t have to worry about runtime and host dependencies. Looking long-term: it provides the ability to run the latest available version of .NET without waiting for a Functions upgrade.

As its in early preview, it does take some work to get going with it, but ultimately it’s great news for getting Azure Functions to support new .NET releases much sooner.

At work, we had a hackathon of sorts to build an authentication API to validate Azure runbooks, and roll it out to production in two weeks (a mostly fun exercise). I hadn’t built out an ASP.NET Core Web API from scratch in awhile, and implemented health checks.

Of course, I knew you could add an endpoint in your middleware for a simple check:

public void Configure(IApplicationBuilder app)
    app.UseEndpoints(endpoints =>

There’s a ton of configuration options at your disposal, and after reading Kevin Griffin’s timely blog post, I learned about the AspNetCore.Diagnostics.HealthChecks library. Did you know about this? Where have I been? You can plug into health check packages for widely used services like Kubernetes, Redis, Postgres, and more. There’s even a UI you can leverage. In case you weren’t aware—maybe you were—I hope you find it helpful.

🌎 Last week in the .NET world

🔥 The Top 4

📢 Announcements

📅 Community and events

🌎 Web development

🥅 The .NET platform

⛅ The cloud

📔 Languages

🔧 Tools

📱 Xamarin

🎤 Podcasts

🎥 Videos

.NET Stacks