Zoo 105 Podcast: Migrating of Azure Function from .NET 6 to .NET 8 isolated

Zoo 105 Podcast: Migrating of Azure Function from .NET 6 to .NET 8 isolated

I continue the list of articles about the Zoo di 105 with my last update, from .NET 6 to .NET 8.
This should have theoretically been an easy update, but in the end it resulted as one of the most demanding, because of a series of issues that I will list here below.

Upgrade from .NET 6 to .NET 8

Upgrading a generic application from .NET 6 to .NET 8 is generally straightforward:

  • change the version in the .csproj project files;
  • if you have a global.json file, update the .NET SDK version used for the compilation;
  • upgrade eventual NuGet packages, in particular the ones related to the .NET version you are using;
  • finally, fix the additional warnings introduced in the latest versions of the .NET Code Analysis.

NuGet Packages

About the NuGet packages, for the first time I have introduced in the project a Directory.Packages.props file.
This file was introduced one year ago in Introducing Central Package Management. It allows to centralize NuGet packages versions in your solution and in particular avoid non-consistent versions across different projects in your solution.

The biggest and heaviest change has been the replacement of the WindowsAzure and Microsoft.Azure.WebJobs packages:

  • the WindowsAzure packages are considered deprecated since more than one year and should be replaced with the Azure packages. The issue here is that there is not just a change of namespaces, but also in classes and methods. Luckily my code was well structured, and I've created methods to perform the basic operations on storage (blobs and queues) and CosmosDB, so I needed to update just these methods, that were used all across the solution.
  • the Microsoft.Azure.WebJobs packages are not deprecated, but must be replaced as well, when moving to the isolated process model. The issue here is that there is some confusion with our documentation, and even GitHub Copilot gets confused from the same attributes in different NuGet packages.

dotnet-isolated

.NET 8 Azure Functions must be run with the dotnet-isolated model. See the announcement GA: Azure Functions supports .NET 8 in the isolated worker model and the guideline on how to perform the upgrade: Guide for running C# Azure Functions in an isolated worker process.

This has required in particular the creation of a Program.cs where the IHost gets instantiated to support Dependency Injection:

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace Zoo105Podcast;

public static class Program
{
	public static async Task Main()
	{
		var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");

		var host = new HostBuilder()
			.ConfigureFunctionsWorkerDefaults()
			.ConfigureServices((hostContext, services) =>
			{
				// https://learn.microsoft.com/en-us/azure/azure-functions/dotnet-isolated-process-guide?tabs=windows
				services.AddApplicationInsightsTelemetryWorkerService();
				services.ConfigureFunctionsApplicationInsights();
			})
			.ConfigureAppConfiguration(builder =>
			{
				builder
					.SetBasePath(Directory.GetCurrentDirectory())
					.AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
					.AddJsonFile($"appsettings.{environment}.json", optional: true, reloadOnChange: true)
					.AddEnvironmentVariables();
				var config = builder.Build();
			})
			.Build();

		await host.RunAsync().ConfigureAwait(false);
	}
}

What is left out (at the moment)

At the moment what I am missing is registering the Azure client with Dependency Injection, like described at Register Azure clients.
The issue that I have is that I have the connection strings in the appsettings.json file (I don't use an Azure KeyVault yet) and I have not found they way to instantiate these DI classes with a full connection string.