|
| 1 | +--- |
| 2 | +title: Overview of Durable Functions in the .NET isolated worker - Azure |
| 3 | +description: Learn about Durable Functions in the Azure Functions .NET isolated worker process, which supports non-LTS versions of .NET and .NET Framework apps. |
| 4 | +author: jviau |
| 5 | +ms.topic: overview |
| 6 | +ms.date: 01/24/2023 |
| 7 | +ms.author: azfuncdf |
| 8 | +ms.devlang: csharp |
| 9 | +#Customer intent: As a developer, I want to learn about Durable Functions for the Azure Functions .NET isolated worker process. |
| 10 | +--- |
| 11 | + |
| 12 | +# Overview of Durable Functions in the .NET isolated worker |
| 13 | + |
| 14 | +This article is an overview of Durable Functions in the [.NET isolated worker](../dotnet-isolated-process-guide.md). The isolated worker allows your Durable Functions app to run on a .NET version different than that of the Azure Functions host. |
| 15 | + |
| 16 | +## Why use Durable Functions in the .NET isolated worker? |
| 17 | + |
| 18 | +Using this model lets you get all the great benefits that come with the Azure Functions .NET isolated worker process. For more information, see [here](../dotnet-isolated-process-guide.md#why-net-functions-isolated-worker-process). Additionally, this new SDK includes some new [features](#feature-improvements-over-in-process-durable-functions). |
| 19 | + |
| 20 | +### Feature improvements over in-process Durable Functions |
| 21 | + |
| 22 | +- Orchestration input can be injected directly: `MyOrchestration([OrchestrationTrigger] TaskOrchestrationContext context, T input)` |
| 23 | +- Support for strongly typed calls and class-based activities and orchestrations (NOTE: in preview. For more information, see [here](#source-generator-and-class-based-activities-and-orchestrations).) |
| 24 | +- Plus all the benefits of the Azure Functions .NET isolated worker. |
| 25 | + |
| 26 | +### Feature parity with in-process Durable Functions |
| 27 | + |
| 28 | +Not all features from in-process Durable Functions have been migrated to the isolated worker yet. Some known missing features that will be addressed at a later date are: |
| 29 | + |
| 30 | +- Durable Entities |
| 31 | +- `CallHttpAsync` |
| 32 | + |
| 33 | +### Source generator and class-based activities and orchestrations |
| 34 | + |
| 35 | +**Requirement**: add `<PackageReference Include="Microsoft.DurableTask.Generators" Version="1.0.0-preview.1" />` to your project. |
| 36 | + |
| 37 | +By adding the source generator package, you get access to two new features: |
| 38 | + |
| 39 | +- **Class-based activities and orchestrations**, an alternative way to write Durable Functions. Instead of "function-based", you write strongly-typed classes, which inherit types from the Durable SDK. |
| 40 | +- **Strongly typed extension methods** for invoking sub orchestrations and activities. These extension methods can also be used from "function-based" activities and orchestrations. |
| 41 | + |
| 42 | +#### Function-based example |
| 43 | + |
| 44 | +```csharp |
| 45 | +public static class MyFunctions |
| 46 | +{ |
| 47 | + [Function(nameof(MyActivity))] |
| 48 | + public static async Task<string> MyActivity([ActivityTrigger] string input) |
| 49 | + { |
| 50 | + // implementation |
| 51 | + } |
| 52 | + |
| 53 | + [Function(nameof(MyOrchestration))] |
| 54 | + public static async Task<string> MyOrchestration([OrchestrationTrigger] TaskOrchestrationContext context, string input) |
| 55 | + { |
| 56 | + // implementation |
| 57 | + return await context.CallActivityAsync(nameof(MyActivity), input); |
| 58 | + } |
| 59 | +} |
| 60 | +``` |
| 61 | + |
| 62 | +#### Class-based example |
| 63 | + |
| 64 | +```csharp |
| 65 | +[DurableTask(nameof(MyActivity))] |
| 66 | +public class MyActivity : TaskActivity<string, string> |
| 67 | +{ |
| 68 | + private readonly ILogger logger; |
| 69 | + |
| 70 | + public MyActivity(ILogger<SayHelloTyped> logger) // activites have access to DI. |
| 71 | + { |
| 72 | + this.logger = logger; |
| 73 | + } |
| 74 | + |
| 75 | + public async override Task<string> RunAsync(TaskActivityContext context, string input) |
| 76 | + { |
| 77 | + // implementation |
| 78 | + } |
| 79 | +} |
| 80 | + |
| 81 | +[DurableTask(nameof(MyOrchestration))] |
| 82 | +public class MyOrchestration : TaskOrchestrator<string, string> |
| 83 | +{ |
| 84 | + public async override Task<string> RunAsync(TaskOrchestrationContext context, string input) |
| 85 | + { |
| 86 | + ILogger logger = context.CreateReplaySafeLogger<MyOrchestration>(); // orchestrations do NOT have access to DI. |
| 87 | +
|
| 88 | + // An extension method was generated for directly invoking "MyActivity". |
| 89 | + return await context.CallMyActivityAsync(input); |
| 90 | + } |
| 91 | +} |
| 92 | +``` |
| 93 | + |
| 94 | +## Migration guide |
| 95 | + |
| 96 | +This guide assumes you're starting with a .NET Durable Functions 2.x project. |
| 97 | + |
| 98 | +### Update your project |
| 99 | + |
| 100 | +The first step is to update your project to [Azure Functions .NET isolated](../migrate-version-3-version-4.md). Then, update your Durable Functions NuGet package references. |
| 101 | + |
| 102 | +Old: |
| 103 | + |
| 104 | +```xml |
| 105 | +<ItemGroup> |
| 106 | + <PackageReference Include="Microsoft.Azure.WebJobs.Extensions.DurableTask" Version="2.9.0" /> |
| 107 | +</ItemGroup> |
| 108 | +``` |
| 109 | + |
| 110 | +New: |
| 111 | + |
| 112 | +```xml |
| 113 | +<ItemGroup> |
| 114 | + <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.DurableTask" Version="1.0.0" /> |
| 115 | +</ItemGroup> |
| 116 | +``` |
| 117 | + |
| 118 | +### Update your code |
| 119 | + |
| 120 | +Durable Functions for .NET isolated worker is an entirely new package with different types and namespaces. There are required changes to your code as a result, but many of the APIs line up with no changes needed. |
| 121 | + |
| 122 | +#### Host.json schema |
| 123 | + |
| 124 | +The schema for Durable Functions .NET isolated worker and Durable Functions 2.x has remained the same, no changes should be needed. |
| 125 | + |
| 126 | +#### Public interface changes |
| 127 | + |
| 128 | +This table isn't an exhaustive list of changes. |
| 129 | + |
| 130 | +| 2.x | Isolated | |
| 131 | +| ---- | ---- | |
| 132 | +| `IDurableOrchestrationClient` | `DurableTaskClient` | |
| 133 | +| `IDurableOrchestrationClient.StartNewAsync` | `DurableTaskClient.ScheduleNewOrchestrationInstanceAsync` | |
| 134 | +| `IDurableOrchestrationContext` | `TaskOrchestrationContext` | |
| 135 | +| `IDurableOrchestrationContext.GetInput<T>()` | `TaskOrchestrationContext.GetInput<T>()` or inject input as a parameter: `MyOrchestration([OrchestrationTrigger] TaskOrchestrationContext context, T input)` | |
| 136 | +| `DurableActivityContext` | No equivalent | |
| 137 | +| `DurableActivityContext.GetInput<T>()` | Inject input as a parameter `MyActivity([ActivityTrigger] T input)` | |
| 138 | +| `CallActivityWithRetryAsync` | `CallActivityAsync`, include `TaskOptions` parameter with retry details. | |
| 139 | +| `CallSubOrchestratorWithRetryAsync` | `CallSubOrchestratorAsync`, include `TaskOptions` parameter with retry details. | |
| 140 | +| `CallHttpAsync` | No equivalent. Instead, write an activity that invokes your desired HTTP API. | |
| 141 | +| `CreateReplaySafeLogger(ILogger)` | `CreateReplaySafeLogger<T>()` or `CreateReplaySafeLogger(string)` | |
| 142 | + |
| 143 | +#### Behavioral changes |
| 144 | + |
| 145 | +- Serialization default behavior has changed from `Newtonsoft.Json` to `System.Text.Json`. For more information, see [here](./durable-functions-serialization-and-persistence.md). |
0 commit comments