Service Fabric Provider
June 19, 2026 · View on GitHub
The Service Fabric provider uses Azure Service Fabric reliable collections for orchestration state. It's designed for applications already running on Service Fabric clusters.
Installation
dotnet add package Microsoft.Azure.DurableTask.AzureServiceFabric
Configuration
Basic Setup
The Service Fabric provider includes built-in infrastructure via TaskHubStatefulService and TaskHubProxyListener:
using DurableTask.AzureServiceFabric;
using DurableTask.AzureServiceFabric.Service;
using DurableTask.Core;
using Microsoft.ServiceFabric.Services.Runtime;
// In Program.cs
ServiceRuntime.RegisterServiceAsync("StatefulServiceType", context =>
{
var settings = new FabricOrchestrationProviderSettings();
var listener = new TaskHubProxyListener(
settings,
RegisterOrchestrations);
return new TaskHubStatefulService(context, new[] { listener });
}).GetAwaiter().GetResult();
void RegisterOrchestrations(TaskHubWorker worker)
{
worker.AddTaskOrchestrations(typeof(MyOrchestration));
worker.AddTaskActivities(typeof(MyActivity));
}
Manual Setup with Provider Factory
For more control, use the FabricOrchestrationProviderFactory:
using DurableTask.AzureServiceFabric;
using DurableTask.Core;
using Microsoft.ServiceFabric.Services.Runtime;
public class DurableTaskService : StatefulService
{
private FabricOrchestrationProvider provider;
private TaskHubWorker worker;
public DurableTaskService(StatefulServiceContext context) : base(context) { }
protected override async Task RunAsync(CancellationToken cancellationToken)
{
var settings = new FabricOrchestrationProviderSettings();
var factory = new FabricOrchestrationProviderFactory(
this.StateManager,
settings);
provider = factory.CreateProvider();
worker = new TaskHubWorker(provider.OrchestrationService, settings.LoggerFactory);
worker.AddTaskOrchestrations(typeof(MyOrchestration));
worker.AddTaskActivities(typeof(MyActivity));
await worker.StartAsync();
try
{
await Task.Delay(Timeout.Infinite, cancellationToken);
}
finally
{
await worker.StopAsync();
provider.Dispose();
}
}
}
Service Registration
Register the service in Program.cs:
ServiceRuntime.RegisterServiceAsync(
"DurableTaskServiceType",
context => new DurableTaskService(context))
.GetAwaiter().GetResult();
Architecture
Reliable Collections
State is stored in Service Fabric reliable collections:
| Collection Name | Purpose |
|---|---|
DtfxSfp_Orchestrations | Orchestration sessions and state |
DtfxSfp_Activities | Pending activity messages |
DtfxSfp_InstanceStore | Instance metadata for queries |
DtfxSfp_ExecutionIdStore | Execution ID mappings |
DtfxSfp_ScheduledMessages | Scheduled timer messages |
DtfxSfp_SessionMessages_{id} | Per-session message queues |
Partitioning
Service Fabric handles partitioning automatically based on your service configuration:
<Service Name="DurableTaskService">
<StatefulService ServiceTypeName="DurableTaskServiceType">
<UniformInt64Partition PartitionCount="4" LowKey="0" HighKey="3" />
</StatefulService>
</Service>
Configuration Options
| Setting | Description | Default |
|---|---|---|
TaskOrchestrationDispatcherSettings.MaxConcurrentOrchestrations | Max concurrent orchestrations | 1000 |
TaskOrchestrationDispatcherSettings.DispatcherCount | Number of orchestration dispatchers | 10 |
TaskActivityDispatcherSettings.MaxConcurrentActivities | Max concurrent activities | 1000 |
TaskActivityDispatcherSettings.DispatcherCount | Number of activity dispatchers | 10 |
LoggerFactory | Optional logger factory for diagnostics | null |
JsonSerializationBinder | ISerializationBinder that restricts which types can be deserialized from incoming JSON requests on the proxy endpoint | AllowedTypesSerializationBinder |
Example Configuration
var settings = new FabricOrchestrationProviderSettings
{
TaskOrchestrationDispatcherSettings =
{
MaxConcurrentOrchestrations = 500,
DispatcherCount = 5
},
TaskActivityDispatcherSettings =
{
MaxConcurrentActivities = 500,
DispatcherCount = 5
}
};
Serialization Security
The proxy endpoint uses TypeNameHandling.All for JSON deserialization to support polymorphic types like HistoryEvent. By default, an AllowedTypesSerializationBinder restricts deserialization to types from DurableTask.Core, DurableTask.AzureServiceFabric, and core system assemblies. This prevents untrusted $type metadata in JSON payloads from loading arbitrary types.
To provide a custom binder:
settings.JsonSerializationBinder = new MyCustomSerializationBinder();
To disable type restrictions and restore legacy behavior:
// ⚠️ Not recommended: disables deserialization type restrictions.
// Only use this if you have other security controls in place
// (e.g., network isolation, mutual TLS) to protect the proxy endpoint.
settings.JsonSerializationBinder = null;
Client Access
From Within Service Fabric
Use the FabricOrchestrationProvider to get both worker and client:
var factory = new FabricOrchestrationProviderFactory(this.StateManager, settings);
var provider = factory.CreateProvider();
var worker = new TaskHubWorker(provider.OrchestrationService, settings.LoggerFactory);
var client = new TaskHubClient(provider.OrchestrationServiceClient, loggerFactory: settings.LoggerFactory);
var instance = await client.CreateOrchestrationInstanceAsync(
typeof(MyOrchestration),
input);
From External Applications
External clients connect via the built-in HTTP API or Service Fabric remoting:
// Create a service proxy
var serviceUri = new Uri("fabric:/MyApp/DurableTaskService");
var proxy = ServiceProxy.Create<IMyDurableTaskService>(serviceUri);
// Call methods on the proxy
var instanceId = await proxy.StartOrchestrationAsync(input);
The TaskHubProxyListener exposes an HTTP API via FabricOrchestrationServiceController for external access.
Limitations
- Requires Service Fabric cluster
- Tightly coupled to Service Fabric ecosystem
- More complex deployment and management
- No external persistence — state is lost if all replicas are lost
Next Steps
- Choosing a Backend — Compare all providers
- Durable Task Scheduler — Recommended managed alternative
- Azure Storage Provider — Alternative self-managed option