Azure functions dotnet isolated model recently started supporting function apps targeting .NET Framework. This is great news for devs maintaining V1 version of function apps because they can now migrate their V1 apps to the latest function runtime version(V4).

Let’s take a look at the version history of function apps with the TFM & hosting models it supported.

Function runtime TFM support
V1 .NET framework, In-proc.only
V2 (Deprecated) .Net core 2.X.
V3 Out of process model is introduced. .NET 5.
In-proc model with .Net core 3.X.
V4 In-proc model with .Net 6.
Out of process model is .Net6, .Net7 and .NET framework.

Until now, function apps created with V1 version could not migrate to the newer versions of functions runtime while maintaining the target framework, but it is possible now with the isolated model support of .NET framework TFM.

The important thing to keep in mind is that, you will be migrating your in-proc app to isolated model.

In-proc to Isolated migration

We will use a very simple V1 function app with Http trigger for the migration example.

1) Update the project file

Open your project file (.csproj) and make the below edits.

  • Update the AzureFunctionsVersion value from v1 to v4.
  • Add OutputType entry with value Exe.
  • Update PackageReferences.

    The in-proc model uses the Microsoft.NET.Sdk.Functions package. In the isolated model, we use a different set of packages.

    The below 2 packages are needed for all isolated function apps.

    The below package is needed for Http functions. Since our example is migrating a function app with HttpTrigger, we need this package as well. In the in-proc model, the Microsoft.NET.Sdk.Functions implicitly brings the Microsoft.Azure.WebJobs.Extensions.Http package for http function support.

So after these changes, your .csproj file will look like this:

The isolated model function app should not have a reference to Microsoft.NET.Sdk.Functions package. That package is only meant for in-proc function apps.

2) Update configuration files

Open your local.settings.json file and add a new entry under Values with key FUNCTIONS_WORKER_RUNTIME and value dotnet-isolated

You can remove AzureWebJobsDashboard entry if present in your config.

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

3) Add a Program.cs with startup code

Create a new class called Program.cs and paste the below code to it.

internal class Program
{
    static void Main(string[] args)
    {
        FunctionsDebugger.Enable();

        var host = new HostBuilder()
            .ConfigureFunctionsWorkerDefaults()
            .Build();

        host.Run();
    }
}

This is the bootstrapping code for the isolated function application. It creates a generic host, configure the services needed for it to work as a function app, build the host and run it. This is where you will register additional dependencies to the DI container or configure logging etc, as needed.

4) Switch to the new types

The v1 in-proc version uses types from the Microsoft.Azure.WebJobs namespace. In the isolated model, we do not use these types, instead a new set of types were introduced in the isolated model. So replace the using statements with using Microsoft.Azure.Functions.Worker from which we will use a few types.

  • In in-proc model, functions are decorated with the FunctionName attribute. In the isolated model, we will use the Function attribute.
  • In the Isolated model, the HttpRequestData type wraps information about the http request, instead of HttpRequestMessage
  • In the Isolated model, the HttpResponseData type should be used as the return type for Http functions.
  • Use the extension methods of HttpRequestData and HttpResponseData to read/write http request/response.
  • For logging, V1 in-proc app uses TraceWriter from Microsoft.Azure.WebJobs.Host. In the V4 isolated model, you will use the ILogger type. This experience will be same as logging in .net/ASP.NET core apps. You can inject an ILogger instance via constructor injection. See example here
  • You can add a parameter of type FunctionContext in your functions to get contextual information about the function being executed. See example here.

Ideally, An isolated function should not have any reference to the Microsoft.Azure.WebJobs package. Packages with Microsoft.Azure.Functions.Worker prefix is what you need in your isolated function app.

You should be good to run your app now. If you are using Visual studio, press F5 to start debugging.

IDE support

For users who uses Visual Studio as their IDE, you need to use Visual studio 2022 Preview 17.4.0 Preview 3 or later for F5 debugging to work.

If you are still running into issues when debugging a .net framework function app, even after installing preview 3 or later, It is possible that VS failed to automatically update the azure functions tools to latest version. In this case, you shall manually update the azure functions tools using the Options dialog.

Tools -> Options -> Projects & Solutions -> Azure functions and click on the “Check for updates” button.

Check Azure functions tools updates available

Install the updates as needed.

Install Azure functions tools Updates

Restart Visual Studio and try to create a new Azure functions project and you should see “.NET Framework Isolated” in the functions worker dropdown.

Here are some useful links to make your migration experience a breeze:

  1. Guide for running C# Azure Functions in an isolated process
  2. Refer this sample solution which has V1 in-proc project and V4 isolated version of the same.
  3. Isolated function app samples in the dotnet worker repo.
  4. Bindings & Triggers in isolated model
  5. Follow Azure functions on twitter

If you are running into issues with the migration process, please open a new issue in the dotnet worker repo.

Cheers