Removing Secret Strings from Your .NET Aspire Project

If you’re building modern .NET Aspire apps, you’re probably familiar with how service names and resource identifiers are often passed around as string literals, things like "apiservice" or "storage". But these magic strings can lead to headaches: typos, duplication, poor discoverability, and painful refactoring.

Thankfully, there’s a clean and safe way to centralize and manage these identifiers using a shared constants class, removing “secret strings” from your Aspire project. 💥

✨ Credit Where Credit’s Due

First, big thanks to Jeff Fritz for showcasing this pattern in his excellent video: “Organize your .NET Aspire Projects like a Pro!”. I also saw Jeff share this approach during his excellent talk at StirTrek earlier this year. This post builds directly on that idea and shows how you can apply it to both project references and cloud resources like Azure Storage.

🎯 The Problem: Magic Strings in AppHost.cs

Here’s what the typical Aspire AppHost.cs might look like:

1
var apiService = builder.AddProject<Projects.AgentFunction_ApiService>("apiservice");

Or when registering Azure Storage resources:

1
2
3
4
var storage = builder.AddAzureStorage("storage")
                     .RunAsEmulator();
var blobs = storage.AddBlobs("blobs");
var queues = storage.AddQueues("queues");

These string literals ("apiservice", "storage", "blobs", etc.) are fragile and hard to reuse safely across your codebase.

One minor typo and things don’t work and you’re left scratching your head for a while, only to later realize you can’t spell. Been there. 😒

🔧 Step 1: Create a New Shared Project

Create a new class library in your solution:

1
dotnet new classlib -n Shared

This project will house your service and resource names.

💻 Step 2: Define Constants in Shared/Services.cs

Create a static class in the Shared project:

1
2
3
4
5
6
7
8
9
namespace Shared;

public static class Services
{
    public const string ApiService = "apiservice";
    public const string AzureStorage = "storage";
    public const string AzureStorageBlobs = "blobs";
    public const string AzureStorageQueues = "queues";
}

Now you have a single source of truth for all your Aspire identifiers. 🎯

Edit the AppHost.csproj to include a reference to Shared, but be sure to opt out of Aspire’s resource detection using the IsAspireProjectResource="false" attribute:

1
<ProjectReference Include="..\Shared\Shared.csproj" IsAspireProjectResource="false" />

This ensures Aspire doesn’t treat Shared as a resource provider.

🔨 Step 4: Update AppHost.cs to Use Constants

Now refactor your code to use those constants:

⏳ Old

1
var apiService = builder.AddProject<Projects.AgentFunction_ApiService>("apiservice");

✅ New

1
var apiService = builder.AddProject<Projects.ApiService>(Shared.Services.ApiService);

And for Azure Storage:

⏳ Old

1
2
3
4
var storage = builder.AddAzureStorage("storage")
                     .RunAsEmulator();
var blobs = storage.AddBlobs("blobs");
var queues = storage.AddQueues("queues");

✅ New

1
2
3
4
var storage = builder.AddAzureStorage(Shared.Services.AzureStorage)
                     .RunAsEmulator();
var blobs = storage.AddBlobs(Shared.Services.AzureStorageBlobs);
var queues = storage.AddQueues(Shared.Services.AzureStorageQueues);

Cleaner. Safer. Easier to manage. 💡

🎈 Step 5: Reference Shared in Client Projects (Optional)

If you have other Aspire projects (e.g., frontend apps or background workers) that also use these service names, add a project reference to Shared there as well.

And the code then becomes:

1
builder.AddAzureQueueServiceClient(Services.AzureStorageQueues);

Now your whole solution can rely on centralized, strongly-typed service identifiers.

🔔 Bonus: Shorten Project Names

In addition to removing magic strings, you can simplify long project names in Aspire by explicitly specifying the AspireProjectMetadataTypeName metadata type name in your project reference.

⏳ Old

1
<ProjectReference Include="..\AgentFunction.ApiService\AgentFunction.ApiService.csproj" />

This results in awkward long names like:

1
builder.AddProject<Projects.AgentFunction_ApiService>("apiservice");

✅ New

1
2
<ProjectReference Include="..\AgentFunction.ApiService\AgentFunction.ApiService.csproj"
                  AspireProjectMetadataTypeName="ApiService" />

Now you can shorten the reference in AppHost.cs to:

1
builder.AddProject<Projects.ApiService>(Shared.Services.ApiService);

This makes your code cleaner and more readable, especially in solutions with deeply nested or namespaced projects.

💞 Benefits Recap

✅ Eliminate fragile magic strings

✅ Enable compiler support and refactoring

✅ Improve discoverability of services and resources

✅ Keep your solution organized and maintainable

📺 Learn More

👉 Watch Jeff Fritz’s video for a great walkthrough of this and other .NET Aspire tips.

🙌 Final Thoughts

Removing magic strings is a small refactor that pays big dividends in maintainability and clarity. Give it a try in your .NET Aspire project—and say goodbye to those “secret strings” once and for all. 🔓