Why .NET Aspire Components Are Powerful

As well as being able to orchestrate .NET projects, Aspire can also orchestrate the so-called Aspire components. These components are special libraries that add popular packages to our distributed application, which include the following:

  • Distributed cache (e.g. Redis)
  • Databases (e.g. SQL Server, PostgreSQL, etc.)
  • Message brokers (e.g. Kafka, Service bus, etc.)

Today, we will talk about Aspire components, why they are useful, and how to add them to our applications. But first, let me introduce you to my affiliate partner, an online learning platform called Educative.

The platform provided a very wide variety of programming courses. But they don’t just show you how to do things like other platforms do. Their biggest selling point is that they have fully interactive coding playgrounds in most lessons. This means that you can practice the skills that you are learning without having to set up your own development environment. You can even do it on an iPad while commuting!

Those interactive playgrounds don’t just contain small “Hello World” style code snippets you can execute. They contain whole applications, like full-stack web applications, mobile applications, and even distributed applications like the ones that can be built with .NET Aspire. The platform even has its own Android emulator that can be launched in the browser.

But the best thing is that this platform is extremely cheap. For a small subscription fee, you will get access to the whole library of courses. You can check how cheap it is via this link.

So, let’s get back to the Aspire components.

Redis output caching in a starter project

The easiest way to start learning how Aspire components work is to use the Aspire starter project with the Redis output caching option. The full setup of such a project is available here.

This project uses Redis for output caching. Output caching is a performance optimization technique used to store the dynamically generated output of a web page or a part of a web page so that it can be served more quickly on subsequent requests. This reduces the need to reprocess the same data and re-render the same content repeatedly, thereby improving the response time and reducing the load on the server.

By default, output caching is done in memory of the application, which means that if the server restarts or if there are multiple instances of applications running behind a load balancer, output caching will no longer work. When the output is cached on Redis, on the other hand, it will persist even if the app server restarts and will be available to all instances of a distributed application.

For those who are new to Redis, it is an in-memory data structure store commonly used as a database, cache, and message broker. It is known for its high performance, flexibility, and rich set of features. While it stores data in memory, it is hosted separately from the apps that use it and has its own memory. This is why it acts as a distributed cache that many different apps can access.

Configuring Aspire components on the host

An Aspire component typically consists of two NuGet packages:

  • A package that allows hosting an instance of the service on Aspire
  • A package that allows other apps hosted by Aspire to access the service

To install the Redis component and host an instance of Redis on Aspire, we will need to reference the Aspire.Hosting.Redis package from the host project. In the example repo we previously referenced, the host project is called AspireApp.AppHost.

Once we added the reference to the package, we will need to register it as a service. We are doing this in the Program.cs file of the AspireApp.AppHost project by executing the following code:

var cache = builder.AddRedis("cache");

Then, we need to add a reference to this service to the apps that we want to use it in. To do so in this example, we are passing the reference to this variable to the webfrontend service registration by passing it as a parameter into the WithReference() method. This is how the full registration of the webfrontend app looks like:

builder.AddProject<Projects.AspireApp_Web>("webfrontend")
    .WithExternalHttpEndpoints()
    .WithReference(cache)
    .WithReference(apiService);

Because the app registered under the name of webfrontend is a Blazor web application with an in-browser UI, this is exactly the kind of app where output caching is important.

Once we register the component and pass its reference to a service, we can consume it from that service.

Connecting to component services from the apps

Apps inside the host have their own NuGet libraries for connecting to specific components. To enable Redis output caching, we need to reference the Aspire.StackExchange.Redis.OutputCaching package, which is referenced in the AspireApp.Web.csproj file

Then, we register the output caching functionality in the Program.cs file in the AspireApp.Web project by invoking the following code:

builder.AddRedisOutputCache("cache");

Please note that the name that we refer to is the same name we registered the component under in the host app. Service discovery will be used to resolve its address.

With Redis caching enabled, the application will cache its output in Redis instead of the local in-memory cache.

Viewing components in the dashboard

If we launch our playground and wait for the applications to build, we will see the cache service listed on the dashboard:

This time, it’s listed as a Container instead of Project. This is because Aspire runs components as containers and needs containerization technology, such as Docker, to run on the machine.

Wrapping Up

Today, we looked at the common principles of hosting Aspire components. The example we looked at is a Redis component used for output caching which is available in the Aspire started project. However, Aspire has many other component types available, which can be found on the official page that receives regular updates:

https://learn.microsoft.com/en-us/dotnet/aspire/fundamentals/components-overview

We will talk about working with other component types, such as databases and message brokers. However, before we do, let’s talk about integration-testing of Aspire applications. This is what we will cover in the next edition.


P.S. If you want me to help you improve your software development skills, you can check out my courses and my books. You can also book me for one-on-one mentorship.