diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3c9789ae6..06348972a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,15 @@
# Changelog
+## vNext
+
+### Microsoft.DurableTask.Client
+
+- Add new `IDurableTaskClientBuilder AddDurableTaskClient(IServiceCollection, string?)` API
+
+### Microsoft.DurableTask.Worker
+
+- Add new `IDurableTaskWorkerBuilder AddDurableTaskWorker(IServiceCollection, string?)` API
+
## v1.5.0
- Implement work item completion tokens for standalone worker scenarios ([#359](https://github.com/microsoft/durabletask-dotnet/pull/359))
diff --git a/Microsoft.DurableTask.sln b/Microsoft.DurableTask.sln
index a86daa23a..1feeda15d 100644
--- a/Microsoft.DurableTask.sln
+++ b/Microsoft.DurableTask.sln
@@ -83,6 +83,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{CECADD
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shared.AzureManaged.Tests", "test\Shared\AzureManaged.Tests\Shared.AzureManaged.Tests.csproj", "{3272C041-F81D-4C85-A4FB-2A700B5A7A9D}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleAppMinimal", "samples\ConsoleAppMinimal\ConsoleAppMinimal.csproj", "{B48FACA9-A328-452A-BFAE-C4F60F9C7024}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -217,6 +219,10 @@ Global
{3272C041-F81D-4C85-A4FB-2A700B5A7A9D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3272C041-F81D-4C85-A4FB-2A700B5A7A9D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3272C041-F81D-4C85-A4FB-2A700B5A7A9D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B48FACA9-A328-452A-BFAE-C4F60F9C7024}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B48FACA9-A328-452A-BFAE-C4F60F9C7024}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B48FACA9-A328-452A-BFAE-C4F60F9C7024}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B48FACA9-A328-452A-BFAE-C4F60F9C7024}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -258,6 +264,7 @@ Global
{1E5C2E83-7B6B-425A-9C9B-0B887D273B12} = {51DC98A3-0193-4C66-964B-C26C748E25B6}
{CECADDB5-E30A-4CE2-8604-9AC596D4A2DC} = {E5637F81-2FB9-4CD7-900D-455363B142A7}
{3272C041-F81D-4C85-A4FB-2A700B5A7A9D} = {CECADDB5-E30A-4CE2-8604-9AC596D4A2DC}
+ {B48FACA9-A328-452A-BFAE-C4F60F9C7024} = {EFF7632B-821E-4CFC-B4A0-ED4B24296B17}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {AB41CB55-35EA-4986-A522-387AB3402E71}
diff --git a/samples/ConsoleApp/ConsoleApp.csproj b/samples/ConsoleApp/ConsoleApp.csproj
index a11332cd0..2434e53de 100644
--- a/samples/ConsoleApp/ConsoleApp.csproj
+++ b/samples/ConsoleApp/ConsoleApp.csproj
@@ -2,14 +2,24 @@
Exe
- net6.0
+ net8.0
enable
-
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/ConsoleApp/Program.cs b/samples/ConsoleApp/Program.cs
index 5879b4c8f..64068079f 100644
--- a/samples/ConsoleApp/Program.cs
+++ b/samples/ConsoleApp/Program.cs
@@ -8,68 +8,55 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
-IHost host = Host.CreateDefaultBuilder(args)
- .ConfigureServices(services =>
- {
- services.AddDurableTaskClient(builder =>
- {
- // Configure options for this builder. Can be omitted if no options customization is needed.
- builder.Configure(opt => { });
- builder.UseGrpc(); // multiple overloads available for providing gRPC information
+HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
- // AddDurableTaskClient allows for multiple named clients by passing in a name as the first argument.
- // When using a non-default named client, you will need to make this call below to have the
- // DurableTaskClient added directly to the DI container. Otherwise IDurableTaskClientProvider must be used
- // to retrieve DurableTaskClients by name from the DI container. In this case, we are using the default
- // name, so the line below is NOT required as it was already called for us.
- builder.RegisterDirectly();
- });
+IDurableTaskClientBuilder clientBuilder = builder.Services.AddDurableTaskClient()
+ .Configure(opt => { }) // configure options for this builder, if desired.
+ .UseGrpc(); // multiple overloads available for providing gRPC information
- services.AddDurableTaskWorker(builder =>
- {
- // Configure options for this builder. Can be omitted if no options customization is needed.
- builder.Configure(opt => { });
+// OPTIONAL STEP
+// AddDurableTaskClient allows for multiple named clients by passing in a name as the first argument.
+// When using a non-default named client, you will need to make this call below to have the
+// DurableTaskClient added directly to the DI container. Otherwise IDurableTaskClientProvider must be used
+// to retrieve DurableTaskClients by name from the DI container. In this case, we are using the default
+// name, so the line below is NOT required as it was already called for us.
+clientBuilder.RegisterDirectly();
- // Register orchestrators and activities.
- builder.AddTasks(tasks =>
+builder.Services.AddDurableTaskWorker()
+ .Configure(opt => { }) // configure options for this builder.
+ .AddTasks(tasks =>
+ {
+ // Add tasks to the worker.
+ tasks.AddOrchestratorFunc("HelloSequence", async context =>
+ {
+ var greetings = new List
{
- tasks.AddOrchestratorFunc("HelloSequence", async context =>
- {
- var greetings = new List
- {
- await context.CallActivityAsync("SayHello", "Tokyo"),
- await context.CallActivityAsync("SayHello", "London"),
- await context.CallActivityAsync("SayHello", "Seattle"),
- };
-
- return greetings;
- });
-
- tasks.AddActivityFunc("SayHello", (context, city) => $"Hello {city}!");
- });
+ await context.CallActivityAsync("SayHello", "Tokyo"),
+ await context.CallActivityAsync("SayHello", "London"),
+ await context.CallActivityAsync("SayHello", "Seattle"),
+ };
- builder.UseGrpc(); // multiple overloads available for providing gRPC information
+ return greetings;
});
- // Can also configure worker and client options through all the existing options config methods.
- // These are equivalent to the 'builder.Configure' calls above.
- services.Configure(opt => { });
- services.Configure(opt => { });
+ tasks.AddActivityFunc("SayHello", (context, city) => $"Hello {city}!");
+ })
+ .UseGrpc(); // multiple overloads available for providing gRPC information
- // Registry can also be done via options pattern. This is equivalent to the 'builder.AddTasks' call above.
- // You can use all the tools options pattern has available. For example, if you have multiple workers you could
- // use ConfigureAll to add tasks to ALL workers in one go. Otherwise, you need to use
- // named option configuration to register to specific workers (where the name matches the name passed to
- // 'AddDurableTaskWorker(name?, builder)').
- services.Configure(registry => { });
+// OPTIONAL STEP
+// Client and Worker options can also be configured through the options pattern.
+// When using the options pattern, configure with the same name as the builder.
+builder.Services.Configure(opt => { });
+builder.Services.Configure(opt => { });
+builder.Services.Configure(registry => { });
- // You can configure custom data converter multiple ways. One is through worker/client options configuration.
- // Alternatively, data converter will be used from the service provider if available (as a singleton) AND no
- // converter was explicitly set on the options.
- services.AddSingleton(JsonDataConverter.Default);
- })
- .Build();
+// OPTIONAL STEP
+// You can configure custom data converter multiple ways. One is through worker/client options configuration.
+// Alternatively, data converter will be used from the service provider if available (as a singleton) AND no
+// converter was explicitly set on the options.
+builder.Services.AddSingleton(JsonDataConverter.Default);
+IHost host = builder.Build();
await host.StartAsync();
await using DurableTaskClient client = host.Services.GetRequiredService();
@@ -82,4 +69,4 @@ await context.CallActivityAsync("SayHello", "Seattle"),
getInputsAndOutputs: true,
cts.Token);
-Console.WriteLine($"Instance completed: {instance}");
\ No newline at end of file
+Console.WriteLine($"Instance completed: {instance}");
diff --git a/samples/ConsoleAppMinimal/ConsoleAppMinimal.csproj b/samples/ConsoleAppMinimal/ConsoleAppMinimal.csproj
new file mode 100644
index 000000000..2434e53de
--- /dev/null
+++ b/samples/ConsoleAppMinimal/ConsoleAppMinimal.csproj
@@ -0,0 +1,25 @@
+
+
+
+ Exe
+ net8.0
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/ConsoleAppMinimal/Program.cs b/samples/ConsoleAppMinimal/Program.cs
new file mode 100644
index 000000000..089c9fa6a
--- /dev/null
+++ b/samples/ConsoleAppMinimal/Program.cs
@@ -0,0 +1,23 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+// This app differs from samples/ConsoleApp in that we show the absolute minimum code needed to run a Durable Task application.
+
+using ConsoleAppMinimal;
+using Microsoft.DurableTask.Client;
+using Microsoft.DurableTask.Worker;
+using Microsoft.Extensions.Hosting;
+
+HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
+
+builder.Services.AddDurableTaskClient().UseGrpc();
+builder.Services.AddDurableTaskWorker()
+ .AddTasks(tasks =>
+ {
+ tasks.AddOrchestrator();
+ tasks.AddActivity();
+ })
+ .UseGrpc();
+
+IHost host = builder.Build();
+await host.StartAsync();
diff --git a/samples/ConsoleAppMinimal/Tasks.cs b/samples/ConsoleAppMinimal/Tasks.cs
new file mode 100644
index 000000000..addeded56
--- /dev/null
+++ b/samples/ConsoleAppMinimal/Tasks.cs
@@ -0,0 +1,31 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using Microsoft.DurableTask;
+
+namespace ConsoleAppMinimal;
+
+[DurableTask("HelloSequence")]
+public class HelloSequenceOrchestrator : TaskOrchestrator>
+{
+ public override async Task> RunAsync(TaskOrchestrationContext context, string input)
+ {
+ IEnumerable greetings =
+ [
+ await context.CallActivityAsync("SayHello", "Tokyo"),
+ await context.CallActivityAsync("SayHello", "London"),
+ await context.CallActivityAsync("SayHello", "Seattle"),
+ ];
+
+ return greetings;
+ }
+}
+
+[DurableTask("SayHello")]
+public class SayHelloActivity : TaskActivity
+{
+ public override Task RunAsync(TaskActivityContext context, string city)
+ {
+ return Task.FromResult($"Hello {city}!");
+ }
+}
diff --git a/src/Client/Core/DependencyInjection/ServiceCollectionExtensions.cs b/src/Client/Core/DependencyInjection/ServiceCollectionExtensions.cs
index db1eca955..89d4db19b 100644
--- a/src/Client/Core/DependencyInjection/ServiceCollectionExtensions.cs
+++ b/src/Client/Core/DependencyInjection/ServiceCollectionExtensions.cs
@@ -12,6 +12,20 @@ namespace Microsoft.DurableTask.Client;
///
public static class ServiceCollectionExtensions
{
+ ///
+ /// Adds and configures Durable Task worker services to the service collection.
+ ///
+ /// The service collection to add to.
+ /// The name of the builder to add.
+ /// The builder used to configured the .
+ public static IDurableTaskClientBuilder AddDurableTaskClient(this IServiceCollection services, string? name = null)
+ {
+ Check.NotNull(services);
+ IDurableTaskClientBuilder builder = GetBuilder(services, name ?? Options.DefaultName, out bool added);
+ ConditionalConfigureBuilder(services, builder, added);
+ return builder;
+ }
+
///
/// Configures and adds a to the service collection.
///
@@ -37,25 +51,31 @@ public static IServiceCollection AddDurableTaskClient(
services.TryAddSingleton();
IDurableTaskClientBuilder builder = GetBuilder(services, name, out bool added);
configure.Invoke(builder);
+ ConditionalConfigureBuilder(services, builder, added);
+ return services;
+ }
- if (added)
+ static void ConditionalConfigureBuilder(
+ IServiceCollection services, IDurableTaskClientBuilder builder, bool configure)
+ {
+ if (!configure)
{
- // The added toggle logic is because we cannot use TryAddEnumerable logic as
- // we would have to dynamically compile a lambda to have it work correctly.
- ConfigureDurableOptions(services, name);
+ return;
+ }
- // We do not want to register DurableTaskClient type directly so we can keep a max of 1 DurableTaskClients
- // registered, allowing for direct-DI of the default client.
- services.AddSingleton(sp => new DefaultDurableTaskClientProvider.ClientContainer(builder.Build(sp)));
+ // The added toggle logic is because we cannot use TryAddEnumerable logic as
+ // we would have to dynamically compile a lambda to have it work correctly.
+ ConfigureDurableOptions(services, builder.Name);
- if (name == Options.DefaultName)
- {
- // If we have the default options name here, we will inject this client directly.
- builder.RegisterDirectly();
- }
- }
+ // We do not want to register DurableTaskClient type directly so we can keep a max of 1 DurableTaskClients
+ // registered, allowing for direct-DI of the default client.
+ services.AddSingleton(sp => new DefaultDurableTaskClientProvider.ClientContainer(builder.Build(sp)));
- return services;
+ if (builder.Name == Options.DefaultName)
+ {
+ // If we have the default options name here, we will inject this client directly.
+ builder.RegisterDirectly();
+ }
}
static IServiceCollection ConfigureDurableOptions(IServiceCollection services, string name)
diff --git a/src/Client/Core/RELEASENOTES.md b/src/Client/Core/RELEASENOTES.md
index b32377e3d..dfa5b9703 100644
--- a/src/Client/Core/RELEASENOTES.md
+++ b/src/Client/Core/RELEASENOTES.md
@@ -1 +1 @@
-- Fix filter not being passed along in `PurgeAllInstancesAsync` (https://github.com/microsoft/durabletask-dotnet/pull/289)
+- Add new `IDurableTaskClientBuilder AddDurableTaskClient(IServiceCollection, string?)` API
diff --git a/src/Worker/Core/DependencyInjection/ServiceCollectionExtensions.cs b/src/Worker/Core/DependencyInjection/ServiceCollectionExtensions.cs
index 8a9ef74c5..e68c550cf 100644
--- a/src/Worker/Core/DependencyInjection/ServiceCollectionExtensions.cs
+++ b/src/Worker/Core/DependencyInjection/ServiceCollectionExtensions.cs
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
+using Microsoft.DurableTask.Worker.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
@@ -11,6 +12,20 @@ namespace Microsoft.DurableTask.Worker;
///
public static class ServiceCollectionExtensions
{
+ ///
+ /// Adds and configures Durable Task worker services to the service collection.
+ ///
+ /// The service collection to add to.
+ /// The name of the builder to add.
+ /// The builder used to configured the .
+ public static IDurableTaskWorkerBuilder AddDurableTaskWorker(this IServiceCollection services, string? name = null)
+ {
+ Check.NotNull(services);
+ IDurableTaskWorkerBuilder builder = GetBuilder(services, name ?? Options.DefaultName, out bool added);
+ ConditionalConfigureBuilder(services, builder, added);
+ return builder;
+ }
+
///
/// Adds and configures Durable Task worker services to the service collection.
///
@@ -41,16 +56,22 @@ public static IServiceCollection AddDurableTaskWorker(
IDurableTaskWorkerBuilder builder = GetBuilder(services, name, out bool added);
configure.Invoke(builder);
+ ConditionalConfigureBuilder(services, builder, added);
+ return services;
+ }
- if (added)
+ static void ConditionalConfigureBuilder(
+ IServiceCollection services, IDurableTaskWorkerBuilder builder, bool configure)
+ {
+ if (!configure)
{
- // The added toggle logic is because we cannot use TryAddEnumerable logic as
- // we would have to dynamically compile a lambda to have it work correctly.
- ConfigureDurableOptions(services, name);
- services.AddSingleton(sp => builder.Build(sp));
+ return;
}
- return services;
+ // The added toggle logic is because we cannot use TryAddEnumerable logic as
+ // we would have to dynamically compile a lambda to have it work correctly.
+ ConfigureDurableOptions(services, builder.Name);
+ services.AddSingleton(sp => builder.Build(sp));
}
static IServiceCollection ConfigureDurableOptions(IServiceCollection services, string name)
@@ -87,15 +108,10 @@ static IDurableTaskWorkerBuilder GetBuilder(IServiceCollection services, string
///
/// A container which is used to store and retrieve builders from within the .
///
- class BuilderContainer
+ class BuilderContainer(IServiceCollection services)
{
- readonly Dictionary builders = new();
- readonly IServiceCollection services;
-
- public BuilderContainer(IServiceCollection services)
- {
- this.services = services;
- }
+ readonly Dictionary builders = [];
+ readonly IServiceCollection services = services;
public IDurableTaskWorkerBuilder GetOrAdd(string name, out bool added)
{
diff --git a/src/Worker/Core/RELEASENOTES.md b/src/Worker/Core/RELEASENOTES.md
index e69de29bb..c00e885ba 100644
--- a/src/Worker/Core/RELEASENOTES.md
+++ b/src/Worker/Core/RELEASENOTES.md
@@ -0,0 +1 @@
+- Add new `IDurableTaskWorkerBuilder AddDurableTaskWorker(IServiceCollection, string?)` API
diff --git a/test/Abstractions.Tests/TaskNameTests.cs b/test/Abstractions.Tests/TaskNameTests.cs
index 739227e96..b5cfc4350 100644
--- a/test/Abstractions.Tests/TaskNameTests.cs
+++ b/test/Abstractions.Tests/TaskNameTests.cs
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-namespace Microsoft.DurableTask;
+namespace Microsoft.DurableTask.Tests;
public class TaskNameTests
{
diff --git a/test/Client/Core.Tests/DependencyInjection/ServiceCollectionExtensionsTests.cs b/test/Client/Core.Tests/DependencyInjection/ServiceCollectionExtensionsTests.cs
index 7347d61f4..7ddce4d5d 100644
--- a/test/Client/Core.Tests/DependencyInjection/ServiceCollectionExtensionsTests.cs
+++ b/test/Client/Core.Tests/DependencyInjection/ServiceCollectionExtensionsTests.cs
@@ -8,8 +8,22 @@ namespace Microsoft.DurableTask.Client.Tests;
public class ServiceCollectionExtensionsTests
{
+ [Theory]
+ [InlineData(null)]
+ [InlineData("")]
+ [InlineData("MyBuilder")]
+ public void AddDurableTaskClient_SameInstance(string? name)
+ {
+ ServiceCollection services = new();
+ IDurableTaskClientBuilder actual1 = services.AddDurableTaskClient(name);
+ IDurableTaskClientBuilder actual2 = services.AddDurableTaskClient(name);
+
+ actual1.Should().NotBeNull();
+ actual1.Should().BeSameAs(actual2);
+ }
+
[Fact]
- public void AddDurableTaskClient_SameInstance()
+ public void AddDurableTaskClient_SameInstance2()
{
ServiceCollection services = new();
IDurableTaskClientBuilder? actual1 = null;
@@ -21,6 +35,72 @@ public void AddDurableTaskClient_SameInstance()
actual1.Should().BeSameAs(actual2);
}
+ [Theory]
+ [InlineData("")]
+ [InlineData("MyBuilder")]
+ public void AddDurableTaskClient_SameInstance3(string name)
+ {
+ ServiceCollection services = new();
+ IDurableTaskClientBuilder? actual1 = null;
+ IDurableTaskClientBuilder? actual2 = null;
+ services.AddDurableTaskClient(name, builder => actual1 = builder);
+ services.AddDurableTaskClient(name, builder => actual2 = builder);
+
+ actual1.Should().NotBeNull();
+ actual1.Should().BeSameAs(actual2);
+ }
+
+ [Fact]
+ public void AddDurableTaskClient_SameInstance4()
+ {
+ ServiceCollection services = new();
+ IDurableTaskClientBuilder actual1 = services.AddDurableTaskClient();
+ IDurableTaskClientBuilder? actual2 = null;
+ services.AddDurableTaskClient(builder => actual2 = builder);
+
+ actual1.Should().NotBeNull();
+ actual1.Should().BeSameAs(actual2);
+ }
+
+ [Fact]
+ public void AddDurableTaskClient_DifferentNames_NotSame()
+ {
+ ServiceCollection services = new();
+ IDurableTaskClientBuilder actual1 = services.AddDurableTaskClient();
+ IDurableTaskClientBuilder actual2 = services.AddDurableTaskClient("MyBuilder");
+
+ actual1.Should().NotBeNull();
+ actual2.Should().NotBeNull();
+ actual1.Should().NotBeSameAs(actual2);
+ }
+
+ [Fact]
+ public void AddDurableTaskClient_DifferentNames_NotSame2()
+ {
+ ServiceCollection services = new();
+ IDurableTaskClientBuilder? actual1 = null;
+ IDurableTaskClientBuilder? actual2 = null;
+ services.AddDurableTaskClient(builder => actual1 = builder);
+ services.AddDurableTaskClient("MyBuilder", builder => actual2 = builder);
+
+ actual1.Should().NotBeNull();
+ actual2.Should().NotBeNull();
+ actual1.Should().NotBeSameAs(actual2);
+ }
+
+ [Fact]
+ public void AddDurableTaskClient_DifferentNames_NotSame3()
+ {
+ ServiceCollection services = new();
+ IDurableTaskClientBuilder actual1 = services.AddDurableTaskClient();
+ IDurableTaskClientBuilder? actual2 = null;
+ services.AddDurableTaskClient("MyBuilder", builder => actual2 = builder);
+
+ actual1.Should().NotBeNull();
+ actual2.Should().NotBeNull();
+ actual1.Should().NotBeSameAs(actual2);
+ }
+
[Fact]
public void AddDurableTaskClient_HostedServiceAdded()
{
diff --git a/test/Worker/Core.Tests/DependencyInjection/ServiceCollectionExtensionsTests.cs b/test/Worker/Core.Tests/DependencyInjection/ServiceCollectionExtensionsTests.cs
index 672d6eeed..8657c63d0 100644
--- a/test/Worker/Core.Tests/DependencyInjection/ServiceCollectionExtensionsTests.cs
+++ b/test/Worker/Core.Tests/DependencyInjection/ServiceCollectionExtensionsTests.cs
@@ -9,8 +9,22 @@ namespace Microsoft.DurableTask.Worker.Tests;
public class ServiceCollectionExtensionsTests
{
+ [Theory]
+ [InlineData(null)]
+ [InlineData("")]
+ [InlineData("MyBuilder")]
+ public void AddDurableTaskWorker_SameInstance(string? name)
+ {
+ ServiceCollection services = new();
+ IDurableTaskWorkerBuilder actual1 = services.AddDurableTaskWorker(name);
+ IDurableTaskWorkerBuilder actual2 = services.AddDurableTaskWorker(name);
+
+ actual1.Should().NotBeNull();
+ actual1.Should().BeSameAs(actual2);
+ }
+
[Fact]
- public void AddDurableTaskWorker_SameInstance()
+ public void AddDurableTaskWorker_SameInstance2()
{
ServiceCollection services = new();
IDurableTaskWorkerBuilder? actual1 = null;
@@ -22,6 +36,72 @@ public void AddDurableTaskWorker_SameInstance()
actual1.Should().BeSameAs(actual2);
}
+ [Theory]
+ [InlineData("")]
+ [InlineData("MyBuilder")]
+ public void AddDurableTaskWorker_SameInstance3(string name)
+ {
+ ServiceCollection services = new();
+ IDurableTaskWorkerBuilder? actual1 = null;
+ IDurableTaskWorkerBuilder? actual2 = null;
+ services.AddDurableTaskWorker(name, builder => actual1 = builder);
+ services.AddDurableTaskWorker(name, builder => actual2 = builder);
+
+ actual1.Should().NotBeNull();
+ actual1.Should().BeSameAs(actual2);
+ }
+
+ [Fact]
+ public void AddDurableTaskWorker_SameInstance4()
+ {
+ ServiceCollection services = new();
+ IDurableTaskWorkerBuilder actual1 = services.AddDurableTaskWorker();
+ IDurableTaskWorkerBuilder? actual2 = null;
+ services.AddDurableTaskWorker(builder => actual2 = builder);
+
+ actual1.Should().NotBeNull();
+ actual1.Should().BeSameAs(actual2);
+ }
+
+ [Fact]
+ public void AddDurableTaskWorker_DifferentNames_NotSame()
+ {
+ ServiceCollection services = new();
+ IDurableTaskWorkerBuilder actual1 = services.AddDurableTaskWorker();
+ IDurableTaskWorkerBuilder actual2 = services.AddDurableTaskWorker("MyBuilder");
+
+ actual1.Should().NotBeNull();
+ actual2.Should().NotBeNull();
+ actual1.Should().NotBeSameAs(actual2);
+ }
+
+ [Fact]
+ public void AddDurableTaskWorker_DifferentNames_NotSame2()
+ {
+ ServiceCollection services = new();
+ IDurableTaskWorkerBuilder? actual1 = null;
+ IDurableTaskWorkerBuilder? actual2 = null;
+ services.AddDurableTaskWorker(builder => actual1 = builder);
+ services.AddDurableTaskWorker("MyBuilder", builder => actual2 = builder);
+
+ actual1.Should().NotBeNull();
+ actual2.Should().NotBeNull();
+ actual1.Should().NotBeSameAs(actual2);
+ }
+
+ [Fact]
+ public void AddDurableTaskWorker_DifferentNames_NotSame3()
+ {
+ ServiceCollection services = new();
+ IDurableTaskWorkerBuilder actual1 = services.AddDurableTaskWorker();
+ IDurableTaskWorkerBuilder? actual2 = null;
+ services.AddDurableTaskWorker("MyBuilder", builder => actual2 = builder);
+
+ actual1.Should().NotBeNull();
+ actual2.Should().NotBeNull();
+ actual1.Should().NotBeSameAs(actual2);
+ }
+
[Fact]
public void AddDurableTaskWorker_HostedServiceAdded()
{