public interface ISomeService { Task DoSomething(); } public class SomeService : ISomeService { public async Task DoSomething() { await Task.Delay(1000); } }
Using TaskEntity<T> with Constructor Injection
public class HelloHistoryState { [JsonPropertyName("messages")] public List<string> Messages { get; set; } = []; } public class HelloHistoryEntity : TaskEntity<HelloHistoryState> { private readonly ISomeService _someService; public HelloHistoryEntity(ISomeService cacheService) { _someService = cacheService; } public async Task Add(string message) { await _someService.DoSomething(); State.Messages.Add(message); } // Async for future proofing public async Task Reset() { State = new HelloHistoryState(); } // Async for future proofing public Task<HelloHistoryState> GetState() => Task.FromResult(State); [Function(nameof(HelloHistoryEntity))] public Task DispatchAsync([EntityTrigger] TaskEntityDispatcher dispatcher) { return dispatcher.DispatchAsync(this); } }
- The entity class inherits from TaskEntity<T> where T is the state type
- Constructor injection works as expected
- The State property provides access to the entity's state
- The DispatchAsync method uses dispatcher.DispatchAsync(this) to dispatch to the entity instance
[Function(nameof(RunOrchestrator))] public static async Task<HelloHistoryState> RunOrchestrator( [OrchestrationTrigger] TaskOrchestrationContext context) { EntityInstanceId entityId = new(nameof(HelloHistoryEntity), "helloHistory"); await context.Entities.CallEntityAsync(entityId, nameof(HelloHistoryEntity.Reset)); string result = await context.CallActivityAsync<string>(nameof(SayHello), "Tokyo"); await context.Entities.CallEntityAsync(entityId, nameof(HelloHistoryEntity.Add), result); result = await context.CallActivityAsync<string>(nameof(SayHello), "Seattle"); await context.Entities.CallEntityAsync(entityId, nameof(HelloHistoryEntity.Add), result); result = await context.CallActivityAsync<string>(nameof(SayHello), "London"); await context.Entities.CallEntityAsync(entityId, nameof(HelloHistoryEntity.Add), result); HelloHistoryState state = await context.Entities.CallEntityAsync<HelloHistoryState>(entityId, nameof(HelloHistoryEntity.GetState)); return state; } [Function(nameof(SayHello))] public static string SayHello([ActivityTrigger] string name, FunctionContext executionContext) { return $"Hello {name}!"; }
Using TaskEntity<T> with ActivatorUtilities
public class HelloHistoryEntity : TaskEntity<HelloHistoryState> { private readonly ISomeService _someService; private readonly CancellationToken _cancellationToken; // Constructor: ISomeService from DI, CancellationToken as manual parameter public HelloHistoryEntity(ISomeService someService, CancellationToken cancellationToken) { _someService = someService; _cancellationToken = cancellationToken; } public async Task Add(string message) { _cancellationToken.ThrowIfCancellationRequested(); await _someService.DoSomething(); State.Messages.Add(message); } // Async for future proofing public async Task Reset() { State = new HelloHistoryState(); } // Async for future proofing public Task<HelloHistoryState> GetState() => Task.FromResult(State); [Function(nameof(HelloHistoryEntity))] public static Task Run([EntityTrigger] TaskEntityDispatcher dispatcher, FunctionContext functionContext) { // Create entity using ActivatorUtilities // Resolving services from DI using FunctionContext and also can pass any manual args HelloHistoryEntity entity = ActivatorUtilities.CreateInstance<HelloHistoryEntity>( functionContext.InstanceServices, functionContext.CancellationToken); return dispatcher.DispatchAsync(entity); } }
Jaliya