I would like to have a service that is capable of starting an orchestration. I am using isolated model. Is it possible to inject DurableTaskClient through dependency injection?
I tried configuring service below and while DurableTaskClient gets injected it throws an exception. I suspect GRPC needs to be additionally configured somehow, maybe to point to task hub or something like that.
Any advice?
`
using DurableFuncExperiment;
using Microsoft.Azure.Functions.Worker;
using Microsoft.DurableTask.Client;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWebApplication()
.ConfigureServices(services =>
{
services.AddApplicationInsightsTelemetryWorkerService();
services.ConfigureFunctionsApplicationInsights();
services.AddTransient<DurableTaskService, DurableTaskService>();
services.AddDurableTaskClient((builder) =>
{
builder.UseGrpc();
});
})
.Build();
host.Run();
using Microsoft.DurableTask.Client;
namespace DurableFuncExperiment;
public class DurableTaskService(DurableTaskClient durableTaskClient)
{
public async Task Execute()
{
string instanceId = await durableTaskClient.ScheduleNewOrchestrationInstanceAsync(Function.SayHelloEventOrchestrator);
}
}`
Executed 'Functions.Jobs_SayHelloEventOrchestrator' (Failed, Id=9bc3cec2-749e-4a4a-9f6a-1b821839d6d4, Duration=6741ms) [2024-10-11T03:24:15.460Z] System.Private.CoreLib: Exception while executing function: Functions.Jobs_SayHelloEventOrchestrator. System.Private.CoreLib: Result: Failure Exception: System.MissingMethodException: Method not found: 'System.String Microsoft.DurableTask.Protobuf.ExecutionStartedEvent.get_CorrelationData()'. [2024-10-11T03:24:15.467Z] at Microsoft.DurableTask.ProtoUtils.ConvertHistoryEvent(HistoryEvent proto) [2024-10-11T03:24:15.469Z] at System.Linq.Enumerable.SelectIListIterator
2.MoveNext() [2024-10-11T03:24:15.475Z] at Microsoft.DurableTask.Worker.Grpc.GrpcOrchestrationRunner.LoadAndRun(String encodedOrchestratorRequest, ITaskOrchestrator implementation, IServiceProvider services) [2024-10-11T03:24:15.479Z] at Microsoft.Azure.Functions.Worker.Extensions.DurableTask.DurableTaskFunctionsMiddleware.RunOrchestrationAsync(FunctionContext context, BindingMetadata triggerBinding, FunctionExecutionDelegate next) in /_/src/Worker.Extensions.DurableTask/DurableTaskFunctionsMiddleware.cs:line 58 [2024-10-11T03:24:15.483Z] at Microsoft.Azure.Functions.Worker.FunctionsApplication.InvokeFunctionAsync(FunctionContext context) in D:\a\_work\1\s\src\DotNetWorker.Core\FunctionsApplication.cs:line 77 [2024-10-11T03:24:15.491Z] at Microsoft.Azure.Functions.Worker.Handlers.InvocationHandler.InvokeAsync(InvocationRequest request) in D:\a\_work\1\s\src\DotNetWorker.Grpc\Handlers\InvocationHandler.cs:line 88 Stack: at Microsoft.DurableTask.ProtoUtils.ConvertHistoryEvent(HistoryEvent proto) [2024-10-11T03:24:15.494Z] at System.Linq.Enumerable.SelectIListIterator
2.MoveNext() [2024-10-11T03:24:15.496Z] at Microsoft.DurableTask.Worker.Grpc.GrpcOrchestrationRunner.LoadAndRun(String encodedOrchestratorRequest, ITaskOrchestrator implementation, IServiceProvider services) [2024-10-11T03:24:15.498Z] at Microsoft.Azure.Functions.Worker.Extensions.DurableTask.DurableTaskFunctionsMiddleware.RunOrchestrationAsync(FunctionContext context, BindingMetadata triggerBinding, FunctionExecutionDelegate next) in //src/Worker.Extensions.DurableTask/DurableTaskFunctionsMiddleware.cs:line 58 [2024-10-11T03:24:15.501Z] at Microsoft.Azure.Functions.Worker.FunctionsApplication.InvokeFunctionAsync(FunctionContext context) in D:\a_work\1\s\src\DotNetWorker.Core\FunctionsApplication.cs:line 77 [2024-10-11T03:24:15.511Z] at Microsoft.Azure.Functions.Worker.Handlers.InvocationHandler.InvokeAsync(InvocationRequest request) in D:\a_work\1\s\src\DotNetWorker.Grpc\Handlers\InvocationHandler.cs:line 88. [2024-10-11T03:24:15.514Z] ede0fd849a0d409b9f0c4bee61e938fb: Function 'Jobs_SayHelloEventOrchestrator (Orchestrator)' failed with an error. Reason: Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Exception while executing function: Functions.Jobs_SayHelloEventOrchestrator [2024-10-11T03:24:15.517Z] ---> Microsoft.Azure.WebJobs.Script.Workers.Rpc.RpcException: Result: Failure Exception: System.MissingMethodException: Method not found: 'System.String Microsoft.DurableTask.Protobuf.ExecutionStartedEvent.get_CorrelationData()'. [2024-10-11T03:24:15.521Z] at Microsoft.DurableTask.ProtoUtils.ConvertHistoryEvent(HistoryEvent proto) [2024-10-11T03:24:15.523Z] at System.Linq.Enumerable.SelectIListIterator2.MoveNext() [2024-10-11T03:24:15.524Z] at Microsoft.DurableTask.Worker.Grpc.GrpcOrchestrationRunner.LoadAndRun(String encodedOrchestratorRequest, ITaskOrchestrator implementation, IServiceProvider services) [2024-10-11T03:24:15.526Z] at Microsoft.Azure.Functions.Worker.Extensions.DurableTask.DurableTaskFunctionsMiddleware.RunOrchestrationAsync(FunctionContext context, BindingMetadata triggerBinding, FunctionExecutionDelegate next) in /_/src/Worker.Extensions.DurableTask/DurableTaskFunctionsMiddleware.cs:line 58 [2024-10-11T03:24:15.528Z] at Microsoft.Azure.Functions.Worker.FunctionsApplication.InvokeFunctionAsync(FunctionContext context) in D:\a\_work\1\s\src\DotNetWorker.Core\FunctionsApplication.cs:line 77 [2024-10-11T03:24:15.530Z] at Microsoft.Azure.Functions.Worker.Handlers.InvocationHandler.InvokeAsync(InvocationRequest request) in D:\a\_work\1\s\src\DotNetWorker.Grpc\Handlers\InvocationHandler.cs:line 88 Stack: at Microsoft.DurableTask.ProtoUtils.ConvertHistoryEvent(HistoryEvent proto) [2024-10-11T03:24:15.535Z] at System.Linq.Enumerable.SelectIListIterator
2.MoveNext() [2024-10-11T03:24:15.537Z] at Microsoft.DurableTask.Worker.Grpc.GrpcOrchestrationRunner.LoadAndRun(String encodedOrchestratorRequest, ITaskOrchestrator implementation, IServiceProvider services) [2024-10-11T03:24:15.540Z] at Microsoft.Azure.Functions.Worker.Extensions.DurableTask.DurableTaskFunctionsMiddleware.RunOrchestrationAsync(FunctionContext context, BindingMetadata triggerBinding, FunctionExecutionDelegate next) in //src/Worker.Extensions.DurableTask/DurableTaskFunctionsMiddleware.cs:line 58 [2024-10-11T03:24:15.542Z] at Microsoft.Azure.Functions.Worker.FunctionsApplication.InvokeFunctionAsync(FunctionContext context) in D:\a_work\1\s\src\DotNetWorker.Core\FunctionsApplication.cs:line 77 [2024-10-11T03:24:15.544Z] at Microsoft.Azure.Functions.Worker.Handlers.InvocationHandler.InvokeAsync(InvocationRequest request) in D:\a_work\1\s\src\DotNetWorker.Grpc\Handlers\InvocationHandler.cs:line 88 [2024-10-11T03:24:15.546Z] at Microsoft.Azure.WebJobs.Script.Description.WorkerFunctionInvoker.InvokeCore(Object[] parameters, FunctionInvocationContext context) in //src/WebJobs.Script/Description/Workers/WorkerFunctionInvoker.cs:line 101 [2024-10-11T03:24:15.551Z] at Microsoft.Azure.WebJobs.Script.Description.FunctionInvokerBase.Invoke(Object[] parameters) in //src/WebJobs.Script/Description/FunctionInvokerBase.cs:line 82 [2024-10-11T03:24:15.553Z] at Microsoft.Azure.WebJobs.Script.Description.FunctionGenerator.Coerce[T](Task1 src) in /_/src/WebJobs.Script/Description/FunctionGenerator.cs:line 225 [2024-10-11T03:24:15.556Z] at Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker
2.InvokeAsync(Object instance, Object[] arguments) in D:\a_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionInvoker.cs:line 53 [2024-10-11T03:24:15.558Z] at Microsoft.Azure.WebJobs.Extensions.DurableTask.OutOfProcMiddleware.<>c__DisplayClass10_0.<b__0>d.MoveNext() in D:\a_work\1\s\src\WebJobs.Extensions.DurableTask\OutOfProcMiddleware.cs:line 130 [2024-10-11T03:24:15.560Z] --- End of stack trace from previous location --- [2024-10-11T03:24:15.561Z] at Microsoft.Azure.WebJobs.Host.Executors.TriggeredFunctionExecutor`1.<>c__DisplayClass7_0.<b__0>d.MoveNext() in D:\a_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\TriggeredFunctionExecutor.cs:line 51 [2024-10-11T03:24:15.563Z] --- End of stack trace from previous location --- [2024-10-11T03:24:15.568Z] at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.InvokeWithTimeoutAsync(IFunctionInvoker invoker, ParameterHelper parameterHelper, CancellationTokenSource timeoutTokenSource, CancellationTokenSource functionCancellationTokenSource, Boolean throwOnTimeout, TimeSpan timerInterval, IFunctionInstance instance) in D:\a_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 581 [2024-10-11T03:24:15.572Z] at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithWatchersAsync(IFunctionInstanceEx instance, ParameterHelper parameterHelper, ILogger logger, CancellationTokenSource functionCancellationTokenSource) in D:\a_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 527 [2024-10-11T03:24:15.574Z] at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstanceEx instance, FunctionStartedMessage message, FunctionInstanceLogEntry instanceLogEntry, ParameterHelper parameterHelper, ILogger logger, CancellationToken cancellationToken) in D:\a_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 306 [2024-10-11T03:24:15.576Z] --- End of inner exception stack trace --- [2024-10-11T03:24:15.578Z] at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstanceEx instance, FunctionStartedMessage message, FunctionInstanceLogEntry instanceLogEntry, ParameterHelper parameterHelper, ILogger logger, CancellationToken cancellationToken) in D:\a_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 352 [2024-10-11T03:24:15.583Z] at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.TryExecuteAsync(IFunctionInstance functionInstance, CancellationToken cancellationToken) in D:\a_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 108. IsReplay: False. State: Failed. RuntimeStatus: Failed. HubName: TestHubName. AppName: . SlotName: . ExtensionVersion: 2.13.1. SequenceNumber: 11. TaskEventId: -1
You need to make sure that you are using correct packages and also verify your code. I am sharing my code here which I have used for testing purpose.
I have following packages in .csproj file.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>_79076732</RootNamespace>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.23.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.DurableTask" Version="1.1.7" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.2.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="1.3.2" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.18.1" />
<PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.22.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.4.0" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Using Include="System.Threading.ExecutionContext" Alias="ExecutionContext" />
</ItemGroup>
</Project>
I have created a separate file named DurableTaskService which has below given code.
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.DurableTask.Client;
namespace _79076732
{
public class DurableTaskService
{
private readonly DurableTaskClient _durableTaskClient;
public DurableTaskService(DurableTaskClient durableTaskClient)
{
_durableTaskClient = durableTaskClient;
}
public async Task<HttpResponseData> ExecuteAsync(HttpRequestData req)
{
string instanceId = await _durableTaskClient.ScheduleNewOrchestrationInstanceAsync("SayHelloEventOrchestrator");
Console.WriteLine($"Started orchestration with ID = {instanceId}");
var result = await _durableTaskClient.CreateCheckStatusResponseAsync(req, instanceId);
return result;
}
}
}
Then I registered it in program.cs file.
using _79076732;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Azure.Functions.Worker;
using Microsoft.DurableTask.Client;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWebApplication()
.ConfigureServices(services =>
{
services.AddApplicationInsightsTelemetryWorkerService();
services.ConfigureFunctionsApplicationInsights();
services.Configure<KestrelServerOptions>(options =>
{
options.AllowSynchronousIO = true;
});
services.AddTransient<DurableTaskService, DurableTaskService>();
services.AddDurableTaskClient((builder) =>
{
builder.UseGrpc();
});
})
.Build();
host.Run();
Lastly, I am invoking DurableTaskService using a http triggered function.
using Microsoft.DurableTask;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;
namespace _79076732
{
public class Function1
{
private readonly DurableTaskService _durableTaskService;
public Function1 (DurableTaskService durableTaskService)
{
_durableTaskService = durableTaskService;
}
[Function("SayHelloEventOrchestrator")]
public async Task<string> SayHelloOrchestrator([OrchestrationTrigger] TaskOrchestrationContext context)
{
var result = await context.CallActivityAsync<string>("SayHello", "Afreen");
return result;
}
[Function("SayHello")]
public string SayHello([ActivityTrigger] string name)
{
return $"Hello, {name}!";
}
[Function("StartOrchestration")]
public async Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req, FunctionContext executionContext)
{
var logger = executionContext.GetLogger("StartOrchestrationFunction");
logger.LogInformation("Starting orchestration...");
var orchestrationResult = await _durableTaskService.ExecuteAsync(req);
return orchestrationResult;
}
}
}
By doing the above given steps, I am able to get the expected response.
Azure Functions Core Tools
Core Tools Version: 4.0.6280 Commit hash: N/A +421f0144b42047aa289ce691dc6db4fc8b6143e6 (64-bit)
Function Runtime Version: 4.834.3.22875
[2024-10-11T08:04:13.447Z] Found C:\Users\*****\79076732\79076732.csproj. Using for user secrets file configuration.
[2024-10-11T08:04:17.440Z] Azure Functions .NET Worker (PID: 19544) initialized in debug mode. Waiting for debugger to attach...
[2024-10-11T08:04:17.497Z] Worker process started and initialized.
Functions:
StartOrchestration: [GET,POST] http://localhost:7230/api/StartOrchestration
SayHello: activityTrigger
SayHelloEventOrchestrator: orchestrationTrigger
For detailed output, run func with --verbose flag.
[2024-10-11T08:04:22.487Z] Host lock lease acquired by instance ID '0000000000000000000000000D2022A4'.
[2024-10-11T08:04:30.630Z] Executing 'Functions.StartOrchestration' (Reason='This function was programmatically called via the host APIs.', Id=70ee6cb7-000e-462d-b6b0-db15a0d812a2)
[2024-10-11T08:04:31.024Z] Scheduling new SayHelloEventOrchestrator orchestration with instance ID 'c626f9f4c2904356aa9fce247ac270ee' and 0 bytes of input data.
[2024-10-11T08:04:31.024Z] Starting orchestration...
[2024-10-11T08:04:31.226Z] Started orchestration with ID = c626f9f4c2904356aa9fce247ac270ee
[2024-10-11T08:04:31.301Z] Executed 'Functions.StartOrchestration' (Succeeded, Id=70ee6cb7-000e-462d-b6b0-db15a0d812a2, Duration=712ms)
[2024-10-11T08:04:31.320Z] Executing 'Functions.SayHelloEventOrchestrator' (Reason='(null)', Id=fc774ab1-d7fe-42e1-bc68-45c275bcd0f8)
[2024-10-11T08:04:31.508Z] Executed 'Functions.SayHelloEventOrchestrator' (Succeeded, Id=fc774ab1-d7fe-42e1-bc68-45c275bcd0f8, Duration=202ms)
[2024-10-11T08:04:31.567Z] Executing 'Functions.SayHello' (Reason='(null)', Id=f376e280-6741-4eda-9fe2-4d43f79ff1f9)
[2024-10-11T08:04:31.582Z] Executed 'Functions.SayHello' (Succeeded, Id=f376e280-6741-4eda-9fe2-4d43f79ff1f9, Duration=17ms)
[2024-10-11T08:04:31.651Z] Executing 'Functions.SayHelloEventOrchestrator' (Reason='(null)', Id=f52075b5-c10b-4f67-af85-bd933754b8ab)
[2024-10-11T08:04:31.685Z] Executed 'Functions.SayHelloEventOrchestrator' (Succeeded, Id=f52075b5-c10b-4f67-af85-bd933754b8ab, Duration=36ms)