So, what is Aspire anyway?
Writing the first paragraph of the first post in a new blog is always a challenge - and I am out of practice. I was going to make my first post about how to use Ghost with Aspire, but cold opens are for comedians not coders - besides it's rude not to introduce yourself.
My name is Mitch and I'm a member of the Aspire team at Microsoft. I also work on ASP.NET Core and over my time at Microsoft I've done various other things.
I joined the Aspire development effort right around the time we started laying down the first "primitives" of the Aspire app-model. Each time you see the following code in your editor you are looking at an API surface that I and others on the small Aspire team sweated the details over.
var builder = DistributedApplication.CreateBuilder(args);
var cache = builder.AddRedis("cache");
var apiService = builder.AddProject<Projects.Billing_ApiService>("apiservice")
.WithHttpHealthCheck("/health");
builder.AddProject<Projects.Billing_Web>("webfrontend")
.WithExternalHttpEndpoints()
.WithHttpHealthCheck("/health")
.WithReference(cache)
.WaitFor(cache)
.WithReference(apiService)
.WaitFor(apiService);
Default AppHost.cs from starter template showing a front-end, a backend, a Redis cache in a container.
We eventually released our first public preview of Aspire on November 14th, 2023, at .NET Conf. As we approached this date, we started struggling with how to describe Aspire to other people. It is something we struggle with to this day, and it's become something of a running joke on the team.
Most elevator pitches for a new product or service offering can start with a "[insert product name] is a [insert category] with [unique selling proposition]".
What we knew was that developing distributed applications was hard with a staggeringly high concept count. From the the inner loop to the outer loop there are countless friction points associated with launching a multi-process / multi-counter / multi-service dependency application that you are able to test, debug, deploy, operate, and observe.
We say that: "Aspire provides tools, templates, and packages for building observable, production-ready distributed apps. At the center is the app model - a code-first, single source of truth that defines your app's services, resources, and connections." ... really rolls off the tongue doesn't it!
The reality is that our current elevator pitch is much better than the cloud-native word salad that we first used, and it gets at the core of what Aspire is.
App-model at the core
If you look at the code sample above again you can see how we are defining an application and then incrementally describing its components and how they hook together. Some folks might compare it with Infrastructure-as-Code (IaC) but its more abstract than that - and more app centric. Where IaC is more heavily concerned with the definition of the infrastructure down to the finest level of detail - Aspire is more concerned with the interconnections between application dependencies.
The magic of Aspire is that we can take this app-model and use it to provide a local inner-loop development and debugging experience and enrich it at deployment time to deploy real production ready environments.
Some of the members of the team have been having some fun recently streaming "AspiriFridays" where they take an app and "aspirify" it. I recommend taking a look at the Aspire channel on YouTube to see what plugging Aspire into a codebase looks like.
But my app isn't distributed?
A common refrain is that “if all you have is a hammer, everything looks like a nail”. As someone building a product its always worth asking what wouldn’t you use this for?
Firstly, it encourages you to be upfront about the kinds of problems that your product is not good at solving — and secondly it might help identify areas for future investment.
There are some programming efforts that probably don’t get a lot of value from using Aspire. For example, if I was building a single-player game with no external dependencies, launching the game via Aspire probably isn’t going to do much for you in terms of inner loop or outer loop.
The moment you acquire an external dependency however (e.g. a backend service for tracking high scores) — Aspire starts making more sense.
Some commenters who have looked at Aspire have declared that it's not worth using it because they just have a single project/service. That might be true for some folks, but it is almost always the case that your application has a dependency on an external service. Does your app store data in a database?
Developers sometimes tend to define distributed or micro-services applications as collections of services that they themselves have written, but a database engine like Postgres or out-of-process cache like Redis are just services that use a protocol that you didn’t invent. They have the same orchestration requirements as any other service in your application.
For this reason, I often find myself reaching for Aspire even when I’ve only got one service (that I’ve written) in my application — if only to make hooking up the external dependencies easier.
Naysayers, raving fans and inbetweeners
Aspire has been out in some for about 18+ months as of the writing of this article. One of the great things about building frameworks and dev tools at Microsoft is that you tend to get some level of traction in the community by default — which means we have lots of feedback to help guide our efforts.
We’ve had a large number of contributors to the Aspire repository in the form of issues and pull requests which is exciting to see.
Every now and then an issue will get posted up on r/dotnet asking whether they should use Aspire or not. These posts always attract a spectrum of reactions ranging from raving fans to folks that are just getting started, to folks who don’t really see what Aspire has to offer them.
The Aspire team takes great interest in these conversations. We are trying to figure out whether we feature gaps (that we don't know about) and of course we love to hear about the success that people are having. A common trend we are seeing is that despite our challenges "pitching Aspire" - once people try it - they get it.
What's next?
Aspire is fast approaching its second birthday and we've just recently published a roadmap for 2025 to 2026. It's a mixture of big rocks and small refinements informed not only by where we want to take the product, but also the feedback we've gotten from our developer community.
This blog?
Hopefully this post is about as introspective as I'm going to get but I thought it was important to set the backdrop for the content that I post here.
My goal is to post content that drills into various aspects of Aspire that I think are noteworthy and show how I approach plugging application dependencies into an Aspire-based application.
Now ... about using Ghost with Aspire?