.NET Aspire dev-time orchestration for SQL Server integration tests

This is the first in a series of articles showing how to use .NET Aspire's dev-time orchestration to write integration tests for code that uses SQL Server. This first post describes Aspire dev-time orchestration.
Aspire dev-time orchestration
Dev-time orchestration is one of Aspire's most helpful features: it can ensure that when you debug a cloud-based application locally, your application has access to all of the services it needs, such as blob storage or a database. For example, it can launch a new containerised SQL Server instance on your development machine when your application starts.
This means developers don't have to install and configure local databases or emulators before they can get to work on a project. And by spinning up new instances in containers each time debugging starts, Aspire can avoid "It works on my machine™" problems where code accidentally becomes dependent on the way a particular developer's machine is configured.
Simple orchestration example
When you create a new Aspire application, your solution will include an app host project, which provides Aspire with a description of your application's components. In other words, we must tell Aspire what we want it to orchestrate for us. To build this description, the app host first creates an IDistributedApplicationBuilder
:
IDistributedApplicationBuilder builder =
DistributedApplication.CreateBuilder(args);
Our app host describes the resources our application needs by calling methods on this builder. For example, we might declare that we require a SQL Server, and that we need it to contain a single database:
IResourceBuilder<SqlServerServerResource> sql = builder.AddSqlServer("sql");
IResourceBuilder<SqlServerDatabaseResource> sqlDb = sql.AddDatabase("db");
We also tell Aspire about our application code, and how that code uses these resources. For example, if we have an ASP.NET Core web project called MyApp.WebApi
that needs access to the database, we can write this:
builder
.AddProject<Projects.MyApp_WebApi>("webapi")
.WithReference(sqlDb)
.WaitFor(sqlDb);
That WithReference(sqlDb)
tells Aspire that when we run locally, it will need to supply our MyApp.WebApi
project with configuration enabling it to connect to the database in the local SQL Server instance. (Aspire's deployment tooling can also use this same information to work out what needs to be deployed to a cloud environment such as Azure, but I won't be showing that here.)
The WaitFor(sqlDb)
tells Aspire that when we debug the project, it should wait until the database is ready for use before starting the MyApp.WebApi
project.
We now have a simple but complete app host. Next time I'll show how to use this app host code in an integration test that uses Aspire's dev-time orchestration.