Add C# TaskChaining

Signed-off-by: Marc Duiker <marcduiker@users.noreply.github.com>
This commit is contained in:
Marc Duiker 2025-03-18 19:44:53 +01:00
parent bd31cf7d62
commit 3ce6f189eb
No known key found for this signature in database
GPG Key ID: 6A36EA7754473DD7
12 changed files with 178 additions and 0 deletions

View File

@ -0,0 +1,12 @@
using Dapr.Workflow;
namespace TaskChaining.Activities;
internal sealed class Activity1 : WorkflowActivity<string, string>
{
public override Task<string> RunAsync(WorkflowActivityContext context, string input)
{
Console.WriteLine($"{nameof(Activity1)}: Received input: {input}.");
return Task.FromResult($"{input} is" );
}
}

View File

@ -0,0 +1,12 @@
using Dapr.Workflow;
namespace TaskChaining.Activities;
internal sealed class Activity2 : WorkflowActivity<string, string>
{
public override Task<string> RunAsync(WorkflowActivityContext context, string input)
{
Console.WriteLine($"{nameof(Activity2)}: Received input: {input}.");
return Task.FromResult($"{input} task" );
}
}

View File

@ -0,0 +1,12 @@
using Dapr.Workflow;
namespace TaskChaining.Activities;
internal sealed class Activity3 : WorkflowActivity<string, string>
{
public override Task<string> RunAsync(WorkflowActivityContext context, string input)
{
Console.WriteLine($"{nameof(Activity3)}: Received input: {input}.");
return Task.FromResult($"{input} chaining" );
}
}

View File

@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Dapr.Workflow;
using TaskChaining.Activities;
namespace TaskChaining
{
public class ChainingWorkflow : Workflow<string, string>
{
public override async Task<string> RunAsync(WorkflowContext context, string input)
{
var result1 = await context.CallActivityAsync<string>(
nameof(Activity1),
input);
var result2 = await context.CallActivityAsync<string>(
nameof(Activity2),
result1);
var workflowResult = await context.CallActivityAsync<string>(
nameof(Activity3),
result2);
return workflowResult;
}
}
}

View File

@ -0,0 +1,25 @@
using Dapr.Workflow;
using TaskChaining;
using TaskChaining.Activities;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDaprWorkflow(options => {
options.RegisterWorkflow<ChainingWorkflow>();
options.RegisterActivity<Activity1>();
options.RegisterActivity<Activity2>();
options.RegisterActivity<Activity3>();
});
var app = builder.Build();
app.MapPost("/start", async () => {
await using var scope = app.Services.CreateAsyncScope();
var workflowClient = scope.ServiceProvider.GetRequiredService<DaprWorkflowClient>();
var instanceId = await workflowClient.ScheduleNewWorkflowAsync(
name: nameof(ChainingWorkflow),
input: "This");
return Results.Accepted(instanceId);
});
app.Run();

View File

@ -0,0 +1,23 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:5255",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7086;http://localhost:5255",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dapr.Workflow" Version="1.15.2" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

View File

@ -0,0 +1,11 @@
@apphost=http://localhost:5255
### Start the workflow
# @name startWorkflowRequest
POST {{ apphost }}/start
@instanceId={{startWorkflowRequest.response.headers.Location}}
@daprHost=http://localhost:3555
### Get the workflow status
GET {{ daprHost }}/v1.0/workflows/dapr/{{ instanceId }}

View File

@ -0,0 +1,11 @@
version: 1
common:
resourcesPath: ../../resources
apps:
- appID: chaining
appDirPath: .
appPort: 5255
daprHTTPPort: 3555
command: ["dotnet", "run"]
appLogDestination: console
daprdLogDestination: console

View File

@ -0,0 +1,15 @@
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: statestore
spec:
type: state.redis
version: v1
initTimeout: 1m
metadata:
- name: redisHost
value: localhost:6379
- name: redisPassword
value: ""
- name: actorStateStore
value: "true"