Skip to content
Ian Griffiths By Ian Griffiths Technical Fellow I
.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.

FAQs

What is .NET Aspire dev-time orchestration? Dev-time orchestration is one of Aspire's most helpful features. It ensures that when you debug a cloud-based application locally, your application has access to all 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.
How does Aspire dev-time orchestration help avoid 'It works on my machine' problems? Aspire means developers don't have to install and configure local databases or emulators before they can get to work on a project. By spinning up new instances in containers each time debugging starts, Aspire avoids problems where code accidentally becomes dependent on the way a particular developer's machine is configured.
What is an Aspire app host project? When you create a new Aspire application, your solution includes an app host project that provides Aspire with a description of your application's components. The app host creates an IDistributedApplicationBuilder and describes the resources the application needs by calling methods on this builder, such as AddSqlServer for a SQL Server database.
What do WithReference and WaitFor do in Aspire? WithReference tells Aspire that when running locally, it needs to supply a project with configuration enabling it to connect to a resource like a database. WaitFor tells Aspire to wait until the resource is ready for use before starting the dependent project. Aspire's deployment tooling can also use the same information to work out what needs to be deployed to a cloud environment.

Ian Griffiths

Technical Fellow I

Ian Griffiths

Ian has worked in various aspects of computing, including computer networking, embedded real-time systems, broadcast television systems, medical imaging, and all forms of cloud computing. Ian is a Technical Fellow at endjin, and 17 times Microsoft MVP in Developer Technologies. He is the author of O'Reilly's Programming C# 12.0, and has written Pluralsight courses on WPF fundamentals (WPF advanced topics WPF v4) and the TPL. He's a maintainer of Reactive Extensions for .NET, Reaqtor, and endjin's 50+ open source projects. Ian has given over 20 talks while at endjin. Technology brings him joy.