Skip to content

Commit

Permalink
Add dependency injection sample (#30)
Browse files Browse the repository at this point in the history
Fixes #9
  • Loading branch information
cretz authored Jul 18, 2023
1 parent 5638899 commit 51ee82e
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Prerequisites:
* [ActivityWorker](src/ActivityWorker) - Use .NET activities from a workflow in another language.
* [AspNet](src/AspNet) - Demonstration of a generic host worker and an ASP.NET workflow starter.
* [ClientMtls](src/ClientMtls) - How to use client certificate authentication, e.g. for Temporal Cloud.
* [DependencyInjection](src/DependencyInjection) - How to inject dependencies in activities and use generic hosts for workers
* [Encryption](src/Encryption) - End-to-end encryption with Temporal payload codecs.
* [Polling](src/Polling) - Recommended implementation of an activity that needs to periodically poll an external resource waiting its successful completion.
* [Schedules](src/Schedules) - How to schedule workflows to be run at specific times in the future.
Expand Down
7 changes: 7 additions & 0 deletions TemporalioSamples.sln
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TemporalioSamples.Polling.I
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TemporalioSamples.Polling.PeriodicSequence", "src\Polling\PeriodicSequence\TemporalioSamples.Polling.PeriodicSequence.csproj", "{11A5854B-EE6E-4752-9C46-F466503D853B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TemporalioSamples.DependencyInjection", "src\DependencyInjection\TemporalioSamples.DependencyInjection.csproj", "{10E6F7C9-7F6C-4A8E-94A1-99C10F46BBA4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -116,6 +118,10 @@ Global
{11A5854B-EE6E-4752-9C46-F466503D853B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{11A5854B-EE6E-4752-9C46-F466503D853B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{11A5854B-EE6E-4752-9C46-F466503D853B}.Release|Any CPU.Build.0 = Release|Any CPU
{10E6F7C9-7F6C-4A8E-94A1-99C10F46BBA4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{10E6F7C9-7F6C-4A8E-94A1-99C10F46BBA4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{10E6F7C9-7F6C-4A8E-94A1-99C10F46BBA4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{10E6F7C9-7F6C-4A8E-94A1-99C10F46BBA4}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{7AECC7C6-9A21-4B8A-84D9-AFC4F5840CAF} = {1A647B41-53D0-4638-AE5A-6630BAAE45FC}
Expand All @@ -136,5 +142,6 @@ Global
{6935B8AC-160F-463D-BE03-AD6FF31585A3} = {AE21E7F4-B114-4761-81B1-8FA63E9F6BB8}
{DD2DE0CF-C127-461B-B4F1-D4E13BDD3B5D} = {AE21E7F4-B114-4761-81B1-8FA63E9F6BB8}
{11A5854B-EE6E-4752-9C46-F466503D853B} = {AE21E7F4-B114-4761-81B1-8FA63E9F6BB8}
{10E6F7C9-7F6C-4A8E-94A1-99C10F46BBA4} = {1A647B41-53D0-4638-AE5A-6630BAAE45FC}
EndGlobalSection
EndGlobal
6 changes: 6 additions & 0 deletions src/DependencyInjection/IMyDatabaseClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace TemporalioSamples.DependencyInjection;

public interface IMyDatabaseClient
{
Task<string> SelectValueAsync(string table);
}
14 changes: 14 additions & 0 deletions src/DependencyInjection/MyActivities.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace TemporalioSamples.DependencyInjection;

using Temporalio.Activities;

public class MyActivities
{
private readonly IMyDatabaseClient databaseClient;

public MyActivities(IMyDatabaseClient databaseClient) => this.databaseClient = databaseClient;

[Activity]
public Task<string> SelectFromDatabaseAsync(string table) =>
databaseClient.SelectValueAsync(table);
}
7 changes: 7 additions & 0 deletions src/DependencyInjection/MyDatabaseClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace TemporalioSamples.DependencyInjection;

public class MyDatabaseClient : IMyDatabaseClient
{
public Task<string> SelectValueAsync(string table) =>
Task.FromResult($"some-db-value from table {table}");
}
18 changes: 18 additions & 0 deletions src/DependencyInjection/MyWorkflow.workflow.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace TemporalioSamples.DependencyInjection;

using Temporalio.Workflows;

[Workflow]
public class MyWorkflow
{
[WorkflowRun]
public async Task<string> RunAsync()
{
return await Workflow.ExecuteActivityAsync(
(MyActivities act) => act.SelectFromDatabaseAsync("some-db-table"),
new()
{
StartToCloseTimeout = TimeSpan.FromMinutes(5),
});
}
}
54 changes: 54 additions & 0 deletions src/DependencyInjection/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using Temporalio.Client;
using Temporalio.Extensions.Hosting;
using TemporalioSamples.DependencyInjection;

async Task RunWorkerAsync()
{
IHost host = Host.CreateDefaultBuilder(args)
.ConfigureLogging(ctx =>
ctx.AddSimpleConsole().SetMinimumLevel(LogLevel.Information))
.ConfigureServices(ctx =>
ctx.
// Add the database client at the scoped level
AddScoped<IMyDatabaseClient, MyDatabaseClient>().
// Add the worker
AddHostedTemporalWorker(
clientTargetHost: "localhost:7233",
clientNamespace: "default",
taskQueue: "dependency-injection-sample").
// Add the activities class at the scoped level
AddScopedActivities<MyActivities>().
AddWorkflow<MyWorkflow>())
.Build();
await host.RunAsync();
}

async Task ExecuteWorkflowAsync()
{
var client = await TemporalClient.ConnectAsync(new("localhost:7233")
{
LoggerFactory = LoggerFactory.Create(builder =>
builder.
AddSimpleConsole(options => options.TimestampFormat = "[HH:mm:ss] ").
SetMinimumLevel(LogLevel.Information)),
});

Console.WriteLine("Executing workflow");
var result = await client.ExecuteWorkflowAsync(
(MyWorkflow wf) => wf.RunAsync(),
new(id: "dependency-injection-workflow-id", taskQueue: "dependency-injection-sample"));

Console.WriteLine("Workflow result: {0}", result);
}

switch (args.ElementAtOrDefault(0))
{
case "worker":
await RunWorkerAsync();
break;
case "workflow":
await ExecuteWorkflowAsync();
break;
default:
throw new ArgumentException("Must pass 'worker' or 'workflow' as the single argument");
}
14 changes: 14 additions & 0 deletions src/DependencyInjection/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Dependency Injection

This sample shows an activity having a dependency injected and a worker running as a generic host.

To run, first see [README.md](../../README.md) for prerequisites. Then, run the following from this directory
in a separate terminal to start the worker:

dotnet run worker

Then in another terminal, run the workflow from this directory:

dotnet run workflow

This will show logs in the worker window of the workflow running.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<Project Sdk="Microsoft.NET.Sdk.Worker">
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.0" />
</ItemGroup>
</Project>

0 comments on commit 51ee82e

Please sign in to comment.