Azure Functions in .NET 5

Stephanie Lee
Oct 8 · 4 min read

Originally, when .NET 5 was first released in November 2020, there was no general support for Azure Functions. In this piece, I aim to discuss why .NET 5 wasn’t supported for Azure Functions initially and how Microsoft has dealt with these issues. Additionally, I will also be covering whether or not it is worth upgrading your .NET Core 3.1 functions and what the differences between .NET Core 3.1 and .NET 5 Azure Functions are.

As of March 2021, Microsoft announced that Azure Functions are supported running on .NET 5. But why weren’t Azure Functions initially supported?

You were unable to use .NET 5 prior to March 2021, due to tight coupling between the Azure Functions runtime and .NET. This means that Azure functions running in-process are required to run on the same version of .NET as the Functions runtime. To deal with this, Microsoft introduced .NET Isolated Process Functions. This is an out-of-process model which runs a .NET 5 worker process alongside the runtime. It was introduced so that we can run Azure Functions runtime version 3 on .NET 5.

It is worth noting that the future of .NET releases require Azure Functions to run on an isolated process. Additionally, Durable Functions will not be supported on the isolated process until .NET 7 based on the following roadmap.

Source .NET on Azure Functions Roadmap

As per the roadmap above, you may wonder whether or not migrating to .NET 5 is worth it, based on long term support (LTS) not being available until .NET 6.

Due to the future of .NET releases requiring Azure Functions to run in an isolated process, it could be worthwhile to do the work now in hope that the migration from .NET 5 to .NET 6 will be much simpler. Additionally, there are many benefits to using an out-of-process function, such as gaining full control of the process, and using existing .NET code for dependency injection and being able to introduce middleware.

In some cases, such as Durable Functions not being available, you may be required to continue to use .NET Core 3.1 and the in-process model.

You’ll need .NET 5.0 installed and Visual Studio 2019 (version 16.10 or later) with the Azure development workloads also installed to be able to create .NET 5 Azure Functions.

Note: You can use 16.9 but the debugging process is slightly more complicated, using 16.10 means that you can debug using the normal F5 route, ensuring you allow access to the firewall for the .NET Host.

The local.settings.jsonfile is different, where the FUNCTIONS_WORKER_RUNTIMEhas changed from dotnetto dotnet-isolated

{
"IsEncrypted": false,
"Values": {
"FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
"AzureWebJobsStorage": "UseDevelopmentStorage=true"
}

The project file has the TargetFramework set to net5.0and the OutputType as Exe. This new OutputType is required because a .NET 5 Azure Function is essentially a .NET Console App that targets .NET 5. The AzureFunctionsVersion remains as v3.

<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<AzureFunctionsVersion>v3</AzureFunctionsVersion>
<OutputType>Exe</OutputType>
</PropertyGroup>

The following changes will differ based on the type of trigger you use. The following example will be for a HttpTrigger.

The NuGet Packages required to run a HttpTrigger Azure Function in .NET 5 are the following:

  • Microsoft.Azure.Functions.Worker
  • Microsoft.Azure.Functions.Worker.Extensions.Http
  • Microsoft.Azure.Functions.Worker.Sdk

There are some differences between these code snippets. Firstly, the FunctionNameattribute now becomes Function. Additionally, you must now use HttpRequestDataand HttpResponseData. The out-of-process function does not have access to the original HTTP request object, this gets converted to a HttpRequestDataobject.

Using ILoggerdirectly now no longer works and you will receive an ArgumentNullException. To access the ILoggerinstance, you must use the FunctionContextobject passed to your function and call the GetLogger
method.

A Program.csfile now exists in a .NET 5 Azure Function which forms the entry point of the application. I have also included .ConfigureServicesblock, where you will have to move any of your existing dependencies to. You can also set up Middleware here.

Stephanie is a Senior Software Engineer in the External Product Feeds team at ASOS. When she’s not coding, she enjoys RPM and BodyAttack classes at the gym and spending as much time as possible with her two house rabbits.

The ASOS Tech Blog

A collective effort from ASOS's Tech Team, driven and…