Temporalio.Extensions.Hosting
1.3.0
dotnet add package Temporalio.Extensions.Hosting --version 1.3.0
NuGet\Install-Package Temporalio.Extensions.Hosting -Version 1.3.0
<PackageReference Include="Temporalio.Extensions.Hosting" Version="1.3.0" />
paket add Temporalio.Extensions.Hosting --version 1.3.0
#r "nuget: Temporalio.Extensions.Hosting, 1.3.0"
// Install Temporalio.Extensions.Hosting as a Cake Addin #addin nuget:?package=Temporalio.Extensions.Hosting&version=1.3.0 // Install Temporalio.Extensions.Hosting as a Cake Tool #tool nuget:?package=Temporalio.Extensions.Hosting&version=1.3.0
Hosting and Dependency Injection Support
This extension adds support for worker Generic Hosts and activity Dependency Injection to the Temporal .NET SDK.
Quick Start
Add the Temporalio.Extensions.Hosting
package from
NuGet. For example, using the dotnet
CLI:
dotnet add package Temporalio.Extensions.Hosting
To create a worker service, you can do the following:
using Temporalio.Extensions.Hosting;
var builder = Host.CreateApplicationBuilder(args);
// Add a hosted Temporal worker which returns a builder to add activities and workflows
builder.Services.
AddHostedTemporalWorker(
"my-temporal-host:7233",
"my-namespace",
"my-task-queue").
AddScopedActivities<MyActivityClass>().
AddWorkflow<MyWorkflow>();
var host = builder.Build();
// Make sure you use RunAsync and not Run, see https://github.com/temporalio/sdk-dotnet/issues/220
await host.RunAsync();
This creates a hosted Temporal worker which returns a builder. Then MyActivityClass
is added to the service collection
as scoped (via
TryAddScoped
)
and registered on the worker. Also MyWorkflow
is registered as a workflow on the worker.
Since we gave client parameters to the worker, the client connection is made as part of the worker. If desired,
ITemporalClient
can be created via the AddTemporalClient
extension and it will be available as a singleton that can
be used by other dependencies including the hosted worker service.
On the worker for every activity invocation, a new scope is created and the the activity is obtained via the service provider. So if it is registered as scoped the activity is created each time but if it registered as singleton it is created only once and reused. The activity's constructor can be used to accept injected dependencies.
Workflows are inherently self-contained, deterministic units of work and therefore should never call anything external. Therefore, there is no such thing as dependency injection for workflows, their construction and lifetime is managed by Temporal.
Clients
When this extension is depended upon, two overloads for AddTemporalClient
are added as extension methods on
IServiceCollection
in the Microsoft.Extensions.DependencyInjection
namespace which add ITemporalClient
as a
singleton if not already present. One overload accepts an optional client target/namespace and returns an option
builder, and the other accepts an action to configure the options.
Worker Services
When this extension is depended upon, two overloads for AddHostedTemporalWorker
are added as extension methods on
IServiceCollection
in the Microsoft.Extensions.DependencyInjection
.
One overload of AddHostedTemporalWorker
, used in the quick start sample above, accepts the client target host, the
client namespace, and the worker task queue. This form will connect to a client for the worker. The other overload of
AddHostedTemporalWorker
only accepts the worker task queue. In the latter, an ITemporalClient
can either be set on
the services container and therefore reused across workers, or the resulting builder can have client options set.
When called, these register a TemporalWorkerServiceOptions
options class with the container and return a
ITemporalWorkerServiceOptionsBuilder
for configuring the worker service options.
For adding activity classes to the service collection and registering activities with the worker, the following extension methods exist on the builder each accepting activity type:
AddSingletonActivities
-TryAddSingleton
+ register activities on workerAddScopedActivities
-TryAddScoped
+ register activities on workerAddTransientActivities
-TryAddTransient
+ register activities on workerAddStaticActivities
- register activities on worker that all must be staticAddActivitiesInstance
- register activities on worker via an existing instance
These all expect the activity methods to have the [Activity]
attribute on them. If an activity type is already added
to the service collection, ApplyTemporalActivities
can be used to just register the activities on the worker.
For registering workflows on the worker, AddWorkflow
extension method is available. This does nothing to the service
collection because the construction and lifecycle of workflows is managed by Temporal. Dependency injection for
workflows is intentionally not supported.
Other worker and client options can be configured on the builder via the ConfigureOptions
extension method. With no
parameters, this returns an OptionsBuilder<TemporalWorkerServiceOptions>
to use. When provided an action, the options
are available as parameters that can be configured. TemporalWorkerServiceOptions
simply extends
TemporalWorkerOptions
with an added property for optional client options that can be set to connect a client on worker
start instead of expecting a ITemporalClient
to be present on the service collection.
⚠️WARNING: Make sure you use host RunAsync()
and not Run()
(see
this issue)
Activity Dependency Injection without Worker Services
Some users may prefer to manually create the TemporalWorker
without using host support, but still make their
activities created via the service provider. CreateTemporalActivityDefinitions
extension methods are present on
IServiceProvider
that will return a collection of ActivityDefinition
instances for each activity on the type. These
can be added to the TemporalWorkerOptions
directly.
Worker Client Refresh
Some users may need to update the worker's connection to Temporal. It's desirable to do this without stopping the worker entirely, as that will evict the sticky workflow cache.
This can be done by using the IWorkerClientUpdater
.
using Temporalio.Extensions.Hosting;
var builder = Host.CreateApplicationBuilder(args);
// Register a worker client updater.
builder.Services.AddSingleton<TemporalWorkerClientUpdater>();
// Add a hosted Temporal worker which returns a builder to add activities and workflows, along with the worker client updater.
builder.Services.
AddHostedTemporalWorker(
"my-temporal-host:7233",
"my-namespace",
"my-task-queue").
AddScopedActivities<MyActivityClass>().
AddWorkflow<MyWorkflow>().
ConfigureOptions().
Configure<TemporalWorkerClientUpdater>((options, workerClientUpdater) => options.WorkerClientUpdater = workerClientUpdater);
var host = builder.Build();
// You can have a BackgroundService periodically refresh the worker client like this.
TemporalWorkerClientUpdater workerClientUpdater = host.Services.GetRequiredService<TemporalWorkerClientUpdater>();
// Can update the TLS options if you need.
TemporalClientConnectOptions clientConnectOptions = new("my-other-temporal-host:7233")
{
Namespace = "default"
};
ITemporalClient updatedClient = await TemporalClient.ConnectAsync(clientConnectOptions).ConfigureAwait(false);
workerClientUpdater.UpdateClient(updatedClient);
// Make sure you use RunAsync and not Run, see https://github.com/temporalio/sdk-dotnet/issues/220
await host.RunAsync();
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 is compatible. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.6.2
- Microsoft.Extensions.Hosting (>= 7.0.0)
- Temporalio (>= 1.3.0)
-
.NETStandard 2.0
- Microsoft.Extensions.Hosting (>= 7.0.0)
- Temporalio (>= 1.3.0)
-
net6.0
- Microsoft.Extensions.Hosting (>= 7.0.0)
- Temporalio (>= 1.3.0)
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
1.3.0 | 0 | 8/14/2024 |
1.2.0 | 2 | 6/27/2024 |
1.1.2 | 2 | 6/4/2024 |
1.1.1 | 0 | 5/10/2024 |
1.1.0 | 0 | 5/7/2024 |
1.0.0 | 0 | 12/5/2023 |
0.1.0-beta2 | 0 | 10/30/2023 |
0.1.0-beta1 | 0 | 7/24/2023 |
0.1.0-alpha6 | 1 | 6/28/2023 |