Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto-register default DurableTaskClient. Fix multiple registrations #81

Merged
merged 1 commit into from
Nov 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ namespace Microsoft.DurableTask.Client;
/// </summary>
class DefaultDurableTaskClientProvider : IDurableTaskClientProvider
{
readonly IEnumerable<DurableTaskClient> clients;
readonly IEnumerable<ClientContainer> clients;

/// <summary>
/// Initializes a new instance of the <see cref="DefaultDurableTaskClientProvider"/> class.
/// </summary>
/// <param name="clients">The set of clients.</param>
public DefaultDurableTaskClientProvider(IEnumerable<DurableTaskClient> clients)
public DefaultDurableTaskClientProvider(IEnumerable<ClientContainer> clients)
{
this.clients = clients;
}
Expand All @@ -25,7 +25,7 @@ public DefaultDurableTaskClientProvider(IEnumerable<DurableTaskClient> clients)
public DurableTaskClient GetClient(string? name = null)
{
name ??= Options.DefaultName;
DurableTaskClient? client = this.clients.FirstOrDefault(
ClientContainer? client = this.clients.FirstOrDefault(
x => string.Equals(name, x.Name, StringComparison.Ordinal)); // options are case sensitive.

if (client is null)
Expand All @@ -35,6 +35,31 @@ public DurableTaskClient GetClient(string? name = null)
nameof(name), name, $"The value of this argument must be in the set of available clients: [{names}].");
}

return client;
return client.Client;
}

/// <summary>
/// Container for holding a client in memory.
/// </summary>
internal class ClientContainer
{
/// <summary>
/// Initializes a new instance of the <see cref="ClientContainer"/> class.
/// </summary>
/// <param name="client">The client.</param>
public ClientContainer(DurableTaskClient client)
{
this.Client = Check.NotNull(client);
}

/// <summary>
/// Gets the client name.
/// </summary>
public string Name => this.Client.Name;

/// <summary>
/// Gets the client.
/// </summary>
public DurableTaskClient Client { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,16 @@ public static IServiceCollection AddDurableTaskClient(
// 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));

// 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)));
cgillum marked this conversation as resolved.
Show resolved Hide resolved

if (name == Options.DefaultName)
{
// If we have the default options name here, we will inject this client directly.
builder.RegisterDirectly();
}
}

return services;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ public void GetClient_Found_Returns(params string[] clients)
client.Name.Should().Be("client1");
}

static List<DurableTaskClient> CreateClients(params string[] names)
static List<DefaultDurableTaskClientProvider.ClientContainer> CreateClients(params string[] names)
{
return names.Select(n =>
{
Mock<DurableTaskClient> client = new(n, new DurableTaskClientOptions());
return client.Object;
return new DefaultDurableTaskClientProvider.ClientContainer(client.Object);
}).ToList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,19 @@ public void AddDurableTaskClient_HostedServiceAdded()
services.AddDurableTaskClient(builder => { });
services.Should().ContainSingle(
x => x.ServiceType == typeof(IDurableTaskClientProvider) && x.Lifetime == ServiceLifetime.Singleton);
services.Should().ContainSingle(
x => x.ServiceType == typeof(DurableTaskClient) && x.Lifetime == ServiceLifetime.Singleton);
}

[Fact]
public void AddDurableTaskClient_Named_HostedServiceAdded()
{
ServiceCollection services = new();
services.AddDurableTaskClient("named", builder => { });
services.Should().ContainSingle(
x => x.ServiceType == typeof(IDurableTaskClientProvider) && x.Lifetime == ServiceLifetime.Singleton);
services.Should().NotContain(
x => x.ServiceType == typeof(DurableTaskClient) && x.Lifetime == ServiceLifetime.Singleton);
}

[Fact]
Expand Down