Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
The .NET isolated worker lets you run Durable Functions on any supported .NET version independently of the Azure Functions host process. This model gives you full control over dependency injection, middleware, and .NET versioning.
In this article, you learn about:
- Benefits of the isolated worker for Durable Functions
- Getting started with the required packages
- Key differences from in-process APIs and namespaces
- Source generators and class-based syntax (preview) for strongly typed orchestrations
Benefits
The .NET isolated worker provides several advantages for Durable Functions apps:
- Independent .NET versioning: Run your app on .NET 8, .NET 9, or later without waiting for the Functions host to update.
- Full dependency injection: Use standard .NET
IServiceCollection/IServiceProviderpatterns in your activities. - Custom middleware: Add cross-cutting concerns like logging, authentication, or error handling via the Functions worker middleware pipeline.
- Direct input injection: Orchestration input can be injected directly into the trigger method signature:
MyOrchestration([OrchestrationTrigger] TaskOrchestrationContext context, T input). - Strongly typed calls (preview): With the source generator package, you get compile-time–safe invocations for activities and sub-orchestrations. For more information, see Source generators and class-based syntax (preview).
For the full list of isolated worker benefits, see Benefits of the isolated worker model.
Get started
To create a Durable Functions app using the .NET isolated worker:
Install the required NuGet package:
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.DurableTask" Version="1.*" />Use
TaskOrchestrationContextfor orchestrators andDurableTaskClientfor client operations. See the quickstart tutorial for a complete walkthrough.
Key differences from in-process
If you're migrating from or comparing to the in-process model, here are the key differences:
| Area | In-process | .NET isolated worker |
|---|---|---|
| NuGet package | Microsoft.Azure.WebJobs.Extensions.DurableTask |
Microsoft.Azure.Functions.Worker.Extensions.DurableTask |
| Orchestrator context | IDurableOrchestrationContext |
TaskOrchestrationContext |
| Client type | IDurableOrchestrationClient |
DurableTaskClient |
| Activity context | IDurableActivityContext |
TaskActivityContext |
| Namespace | Microsoft.Azure.WebJobs.Extensions.DurableTask |
Microsoft.DurableTask / Microsoft.Azure.Functions.Worker |
| Replay-safe logger | context.CreateReplaySafeLogger(log) |
context.CreateReplaySafeLogger("Name") |
For a comprehensive migration guide that covers project setup, package references, API mappings, behavioral differences, and common issues, see Migrate from in-process to isolated worker model.
Source generators and class-based syntax (preview)
The source generator package provides an alternative to function-based Durable Functions. Instead of static methods with [Function] attributes, you write strongly typed classes that inherit from the Durable SDK.
Prerequisites
Add the source generator NuGet package to your project:
<PackageReference Include="Microsoft.DurableTask.Generators" Version="1.0.0" />
The package provides two capabilities:
- Class-based activities and orchestrations — strongly typed classes that inherit
TaskOrchestrator<TInput, TOutput>andTaskActivity<TInput, TOutput>. - Strongly typed extension methods — compile-time–safe methods for invoking sub-orchestrations and activities. These extension methods also work from function-based orchestrations.
Example
The following example shows a class-based orchestration that calls a class-based activity:
using Microsoft.DurableTask;
[DurableTask]
public class MyOrchestration : TaskOrchestrator<string, string>
{
public override async Task<string> RunAsync(TaskOrchestrationContext context, string input)
{
return await context.CallActivityAsync<string>(nameof(MyActivity), input);
}
}
[DurableTask]
public class MyActivity : TaskActivity<string, string>
{
public override Task<string> RunAsync(TaskActivityContext context, string input)
{
return Task.FromResult($"Processed: {input}");
}
}
Tip
For orchestrations or activities that don't need functional input or output, use object? as the generic type argument (for example, TaskOrchestrator<object?, object?>). This pattern lets you use dependency injection (for example, ILogger<T>) in activities while still using the class-based model.
Durable entities
Durable entities are supported in the .NET isolated worker. For more information, see the developer's guide.