|
| 1 | +--- |
| 2 | +title: Migrate .NET function apps from the in-process model to the isolated worker model |
| 3 | +description: This article shows you how to upgrade your existing .NET function apps running on the in-process model to the isolated worker model. |
| 4 | +ms.service: azure-functions |
| 5 | +ms.custom: devx-track-dotnet |
| 6 | +ms.topic: how-to |
| 7 | +ms.date: 08/2/2023 |
| 8 | +--- |
| 9 | + |
| 10 | +# Migrate .NET apps from the in-process model to the isolated worker model |
| 11 | + |
| 12 | +This article walks you through the process of safely migrating your .NET function app from the [in-process model](./functions-dotnet-class-library.md) to the [isolated worker model][isolated-guide]. To learn about the high-level differences between these models, see the [execution mode comparison](./dotnet-isolated-in-process-differences.md). |
| 13 | + |
| 14 | +This guide assumes that your app is running on version 4.x of the Functions runtime. If not, you should instead follow the guides for upgrading your host version: |
| 15 | + |
| 16 | +- [Migrate apps from Azure Functions version 2.x and 3.x to version 4.x](./migrate-version-3-version-4.md) |
| 17 | +- [Migrate apps from Azure Functions version 1.x to version 4.x](./migrate-version-1-version-4.md) |
| 18 | + |
| 19 | +These host version migration guides will also help you migrate to the isolated worker model as you work through them. |
| 20 | + |
| 21 | +## Identify function apps to upgrade |
| 22 | + |
| 23 | +Use the following PowerShell script to generate a list of function apps in your subscription that currently use the in-process model: |
| 24 | + |
| 25 | +```powershell |
| 26 | +$Subscription = '<YOUR SUBSCRIPTION ID>' |
| 27 | + |
| 28 | +Set-AzContext -Subscription $Subscription | Out-Null |
| 29 | +
|
| 30 | +$FunctionApps = Get-AzFunctionApp |
| 31 | +
|
| 32 | +$AppInfo = @{} |
| 33 | +
|
| 34 | +foreach ($App in $FunctionApps) |
| 35 | +{ |
| 36 | + if ($App.ApplicationSettings["FUNCTIONS_WORKER_RUNTIME"] -eq 'dotnet') |
| 37 | + { |
| 38 | + $AppInfo.Add($App.Name, $App.ApplicationSettings["FUNCTIONS_WORKER_RUNTIME"]) |
| 39 | + } |
| 40 | +} |
| 41 | +
|
| 42 | +$AppInfo |
| 43 | +``` |
| 44 | + |
| 45 | +## Choose your target .NET version |
| 46 | + |
| 47 | +On version 4.x of the Functions runtime, your .NET function app targets .NET 6 when using the in-process model. |
| 48 | + |
| 49 | +[!INCLUDE [functions-dotnet-migrate-v4-versions](../../includes/functions-dotnet-migrate-v4-versions.md)] |
| 50 | + |
| 51 | +> [!TIP] |
| 52 | +> **We recommend upgrading to .NET 6 on the isolated worker model.** This provides a quick upgrade path with the longest support window from .NET. |
| 53 | +
|
| 54 | +## Prepare for migration |
| 55 | + |
| 56 | +If you haven't already, identify the list of apps that need to be migrated in your current Azure Subscription by using the [Azure PowerShell](#identify-function-apps-to-upgrade). |
| 57 | + |
| 58 | +Before you upgrade an app to the isolated worker model, you should thoroughly review the contents of this guide and familiarize yourself with the features of the [isolated worker model][isolated-guide]. |
| 59 | + |
| 60 | +To upgrade the application, you will: |
| 61 | + |
| 62 | +1. Complete the steps in [Upgrade your local project](#upgrade-your-local-project) to migrate your local project to the isolated worker model. |
| 63 | +1. After migrating your project, fully test the app locally using version 4.x of the [Azure Functions Core Tools](functions-run-local.md). |
| 64 | +1. [Upgrade your function app in Azure](#upgrade-your-function-app-in-azure) to the isolated model. |
| 65 | + |
| 66 | +## Upgrade your local project |
| 67 | + |
| 68 | +The section outlines the various changes that you need to make to your local project to move it to the isolated worker model. Some of the steps change based on your target version of .NET. Use the tabs to select the instructions which match your desired version. |
| 69 | + |
| 70 | +> [!TIP] |
| 71 | +> The [.NET Upgrade Assistant] can be used to automatically make many of the changes mentioned in the following sections. |
| 72 | +
|
| 73 | +### .csproj file |
| 74 | + |
| 75 | +The following example is a .csproj project file that uses .NET 6 on version 4.x: |
| 76 | + |
| 77 | +```xml |
| 78 | +<Project Sdk="Microsoft.NET.Sdk"> |
| 79 | + <PropertyGroup> |
| 80 | + <TargetFramework>net6.0</TargetFramework> |
| 81 | + <AzureFunctionsVersion>v4</AzureFunctionsVersion> |
| 82 | + <RootNamespace>My.Namespace</RootNamespace> |
| 83 | + </PropertyGroup> |
| 84 | + <ItemGroup> |
| 85 | + <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.1.1" /> |
| 86 | + </ItemGroup> |
| 87 | + <ItemGroup> |
| 88 | + <None Update="host.json"> |
| 89 | + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> |
| 90 | + </None> |
| 91 | + <None Update="local.settings.json"> |
| 92 | + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> |
| 93 | + <CopyToPublishDirectory>Never</CopyToPublishDirectory> |
| 94 | + </None> |
| 95 | + </ItemGroup> |
| 96 | +</Project> |
| 97 | +``` |
| 98 | + |
| 99 | +Use one of the following procedures to update this XML file to run in the isolated worker model: |
| 100 | + |
| 101 | +# [.NET 6 (isolated)](#tab/net6-isolated) |
| 102 | + |
| 103 | +[!INCLUDE [functions-dotnet-migrate-project-v4-isolated](../../includes/functions-dotnet-migrate-project-v4-isolated.md)] |
| 104 | + |
| 105 | +# [.NET 7](#tab/net7) |
| 106 | + |
| 107 | +[!INCLUDE [functions-dotnet-migrate-project-v4-isolated-2](../../includes/functions-dotnet-migrate-project-v4-isolated-2.md)] |
| 108 | + |
| 109 | +# [.NET Framework 4.8](#tab/v4) |
| 110 | + |
| 111 | +[!INCLUDE [functions-dotnet-migrate-project-v4-isolated-net-framework](../../includes/functions-dotnet-migrate-project-v4-isolated-net-framework.md)] |
| 112 | + |
| 113 | +--- |
| 114 | + |
| 115 | +### Package and namespace changes |
| 116 | + |
| 117 | + When migrating to the isolated worker model, you need to change the packages your application references. Then you need to update the namespace of using statements and some types you reference. You can see the effect of these namespace changes on `using` statements in the [HTTP trigger template examples](#http-trigger-template) section later in this article. |
| 118 | + |
| 119 | +[!INCLUDE [functions-dotnet-migrate-packages-v4-isolated](../../includes/functions-dotnet-migrate-packages-v4-isolated.md)] |
| 120 | + |
| 121 | +### Program.cs file |
| 122 | + |
| 123 | +When migrating to run in an isolated worker process, you must add the following program.cs file to your project: |
| 124 | + |
| 125 | +# [.NET 6 (isolated)](#tab/net6-isolated) |
| 126 | + |
| 127 | +:::code language="csharp" source="~/functions-quickstart-templates/Functions.Templates/ProjectTemplate_v4.x/CSharp-Isolated/Program.cs" range="23-29"::: |
| 128 | + |
| 129 | +# [.NET 7](#tab/net7) |
| 130 | + |
| 131 | +:::code language="csharp" source="~/functions-quickstart-templates/Functions.Templates/ProjectTemplate_v4.x/CSharp-Isolated/Program.cs" range="23-29"::: |
| 132 | + |
| 133 | +# [.NET Framework 4.8](#tab/v4) |
| 134 | + |
| 135 | +:::code language="csharp" source="~/functions-quickstart-templates/Functions.Templates/ProjectTemplate_v4.x/CSharp-Isolated/Program.cs" range="2-20"::: |
| 136 | + |
| 137 | +--- |
| 138 | + |
| 139 | +### local.settings.json file |
| 140 | + |
| 141 | +The local.settings.json file is only used when running locally. For information, see [Local settings file](functions-develop-local.md#local-settings-file). |
| 142 | + |
| 143 | +When migrating from running in-process to running in an isolated worker process, you need to change the `FUNCTIONS_WORKER_RUNTIME` value to "dotnet-isolated". Make sure that your local.settings.json file has at least the following elements: |
| 144 | + |
| 145 | +:::code language="json" source="~/functions-quickstart-templates/Functions.Templates/ProjectTemplate_v4.x/CSharp-Isolated/local.settings.json"::: |
| 146 | + |
| 147 | +### Class name changes |
| 148 | + |
| 149 | +Some key classes change between the in-process model and the isolated worker model. The following table indicates key .NET classes used by Functions that change when migrating: |
| 150 | + |
| 151 | +| In-process model | Isolated worker model| |
| 152 | +| --- | --- | --- | |
| 153 | +| `FunctionName` (attribute) | `Function` (attribute) | |
| 154 | +| `ILogger` | `ILogger`, `ILogger<T>` | |
| 155 | +| `HttpRequest` | `HttpRequestData`, `HttpRequest` (using [ASP.NET Core integration])| |
| 156 | +| `IActionResult` | `HttpResponseData`, `IActionResult` (using [ASP.NET Core integration])| |
| 157 | +| `FunctionsStartup` (attribute) | Uses [`Program.cs`](#programcs-file) instead | |
| 158 | + |
| 159 | +[ASP.NET Core integration]: ./dotnet-isolated-process-guide.md#aspnet-core-integration-preview |
| 160 | + |
| 161 | +There might also be class name differences in bindings. For more information, see the reference articles for the specific bindings. |
| 162 | + |
| 163 | +### HTTP trigger template |
| 164 | + |
| 165 | +The differences between in-process and isolated worker process can be seen in HTTP triggered functions. The HTTP trigger template for the in-process model looks like the following example: |
| 166 | + |
| 167 | +:::code language="csharp" source="~/functions-quickstart-templates/Functions.Templates/Templates/HttpTrigger-CSharp/HttpTriggerCSharp.cs"::: |
| 168 | + |
| 169 | +The HTTP trigger template for the migrated version looks like the following example: |
| 170 | + |
| 171 | +# [.NET 6 (isolated)](#tab/net6-isolated) |
| 172 | + |
| 173 | +:::code language="csharp" source="~/functions-quickstart-templates/Functions.Templates/Templates/HttpTrigger-CSharp-Isolated/HttpTriggerCSharp.cs"::: |
| 174 | + |
| 175 | +You can also leverage [ASP.NET Core integration] to instead have the function look more like the following example: |
| 176 | + |
| 177 | +```csharp |
| 178 | +[Function("HttpFunction")] |
| 179 | +public IActionResult Run( |
| 180 | + [HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequest req) |
| 181 | +{ |
| 182 | + return new OkObjectResult($"Welcome to Azure Functions, {req.Query["name"]}!"); |
| 183 | +} |
| 184 | +``` |
| 185 | + |
| 186 | +# [.NET 7](#tab/net7) |
| 187 | + |
| 188 | +:::code language="csharp" source="~/functions-quickstart-templates/Functions.Templates/Templates/HttpTrigger-CSharp-Isolated/HttpTriggerCSharp.cs"::: |
| 189 | + |
| 190 | +You can also leverage [ASP.NET Core integration] to instead have the function look more like the following example: |
| 191 | + |
| 192 | +```csharp |
| 193 | +[Function("HttpFunction")] |
| 194 | +public IActionResult Run( |
| 195 | + [HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequest req) |
| 196 | +{ |
| 197 | + return new OkObjectResult($"Welcome to Azure Functions, {req.Query["name"]}!"); |
| 198 | +} |
| 199 | +``` |
| 200 | + |
| 201 | +# [.NET Framework 4.8](#tab/v4) |
| 202 | + |
| 203 | +:::code language="csharp" source="~/functions-quickstart-templates/Functions.Templates/Templates/HttpTrigger-CSharp-Isolated/HttpTriggerCSharp.cs"::: |
| 204 | + |
| 205 | +--- |
| 206 | + |
| 207 | +## Upgrade your function app in Azure |
| 208 | + |
| 209 | +Upgrading your function app to the isolated model consists of two steps: |
| 210 | + |
| 211 | +1. Change the configuration of the function app to use the isolated model by setting the `FUNCTIONS_WORKER_RUNTIME` application setting to "dotnet-isolated". Make sure that any deployment automation is similarly updated. |
| 212 | +2. Publish your upgraded project to the upgraded function app. |
| 213 | + |
| 214 | +When you use Visual Studio to publish an isolated worker model project to an existing function app that uses the in-process model, you're prompted to let Visual Studio upgrade the function app during deployment. This accomplishes both steps at once. |
| 215 | + |
| 216 | +If you need to minimize downtime, consider using a [staging slot](functions-deployment-slots.md) to test and verify your upgraded code with your upgraded configuration in Azure. You can then deploy your upgraded app to the production slot through a swap operation. |
| 217 | + |
| 218 | +Once you've completed these steps, your app has been fully migrated to the isolated model. Congratulations! Repeat the steps from this guide as necessary for [any other apps needing migration](#identify-function-apps-to-upgrade). |
| 219 | + |
| 220 | +## Next steps |
| 221 | + |
| 222 | +> [!div class="nextstepaction"] |
| 223 | +> [Learn more about the isolated worker model][isolated-guide] |
| 224 | +
|
| 225 | +[isolated-guide]: ./dotnet-isolated-process-guide.md |
| 226 | +[.NET Upgrade Assistant]: /dotnet/core/porting/upgrade-assistant-overview |
0 commit comments