Skip to content
This repository was archived by the owner on Jun 23, 2025. It is now read-only.
Draft
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 @@ -6,6 +6,7 @@
using System.Threading.Tasks;
using commercetools.Sdk.Client;
using commercetools.Sdk.Domain.Categories;
using commercetools.Sdk.HttpApi;
using commercetools.Sdk.HttpApi.Domain.Exceptions;
using commercetools.Sdk.HttpApi.Tokens;
using Microsoft.Extensions.Configuration;
Expand Down Expand Up @@ -51,6 +52,33 @@ public async Task MultipleClientsSimpleInjector()
Assert.IsType<Domain.Projects.Project>(t2);
}

[Fact]
public async Task MultipleClientsByNameSimpleInjector()
{
var services = new Container();
var configuration = new ConfigurationBuilder().
AddJsonFile("appsettings.test.json").
AddJsonFile("appsettings.test.Development.json", true).
// https://www.jerriepelser.com/blog/aspnet-core-no-more-worries-about-checking-in-secrets/
AddUserSecrets<ServiceProviderFixture>().
AddEnvironmentVariables("CTP_").
Build();

services.UseCommercetools(configuration, new Dictionary<string, TokenFlow>()
{
{ "Client", TokenFlow.ClientCredentials },
{ "TokenClient", TokenFlow.ClientCredentials }
});
var clientFactory = services.GetService<ICtpClientFactory>();
var client1 = clientFactory.Create("Client");
var client2 = clientFactory.Create("TokenClient");

var t1 = await client1.ExecuteAsync(new GetProjectCommand());
Assert.IsType<Domain.Projects.Project>(t1);
var t2 = await client2.ExecuteAsync(new GetProjectCommand());
Assert.IsType<Domain.Projects.Project>(t2);
}

[Fact]
public async Task MultipleClientsBuiltIn()
{
Expand Down Expand Up @@ -81,6 +109,35 @@ public async Task MultipleClientsBuiltIn()
Assert.IsType<Domain.Projects.Project>(t2);
}

[Fact]
public async Task MultipleClientsByNameBuiltIn()
{
var services = new ServiceCollection();
var configuration = new ConfigurationBuilder().
AddJsonFile("appsettings.test.json").
AddJsonFile("appsettings.test.Development.json", true).
// https://www.jerriepelser.com/blog/aspnet-core-no-more-worries-about-checking-in-secrets/
AddUserSecrets<ServiceProviderFixture>().
AddEnvironmentVariables("CTP_").
Build();

services.UseCommercetools(configuration, new Dictionary<string, TokenFlow>()
{
{ "Client", TokenFlow.ClientCredentials },
{ "TokenClient", TokenFlow.ClientCredentials }
});
var serviceProvider = services.BuildServiceProvider();

var clientFactory = serviceProvider.GetService<ICtpClientFactory>();
var client1 = clientFactory.Create("Client");
var client2 = clientFactory.Create("TokenClient");

var t1 = await client1.ExecuteAsync(new GetProjectCommand());
Assert.IsType<Domain.Projects.Project>(t1);
var t2 = await client2.ExecuteAsync(new GetProjectCommand());
Assert.IsType<Domain.Projects.Project>(t2);
}

[Fact]
public async void TestConcurrentRequestsSimpleInject()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ public void GetCategoryById()
IClient commerceToolsClient = new CtpClient(
mockHttpClientFactory.Object,
this.clientFixture.GetService<IHttpApiCommandFactory>(),
this.clientFixture.GetService<ISerializerService>(),
this.clientFixture.GetService<IUserAgentProvider>()
this.clientFixture.GetService<ISerializerService>()
);
string categoryId = "2bafc816-4223-4ff0-ac8a-0f08a8f29fd6";
Category category = commerceToolsClient.ExecuteAsync(new GetByIdCommand<Category>(new Guid(categoryId))).Result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ public void GetMessageByIdForCategoryCreatedAction()
IClient commerceToolsClient = new CtpClient(
mockHttpClientFactory.Object,
this.clientFixture.GetService<IHttpApiCommandFactory>(),
this.clientFixture.GetService<ISerializerService>(),
this.clientFixture.GetService<IUserAgentProvider>()
this.clientFixture.GetService<ISerializerService>()
);
string messageId = "174adf2f-783f-4ce5-a2d5-ee7d3ee7caf4";
CategoryCreatedMessage categoryCreatedMessage = commerceToolsClient.ExecuteAsync(new GetByIdCommand<Message>(new Guid(messageId))).Result as CategoryCreatedMessage;
Expand Down
20 changes: 2 additions & 18 deletions commercetools.Sdk/commercetools.Sdk.HttpApi/CtpClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using System.Net.Http;
using System.Threading.Tasks;
using Client;
using DelegatingHandlers;
using Domain.Exceptions;
using Serialization;

Expand All @@ -12,36 +11,21 @@ public class CtpClient : IClient
private readonly IHttpApiCommandFactory httpApiCommandFactory;
private readonly IHttpClientFactory httpClientFactory;
private readonly ISerializerService serializerService;
private readonly IUserAgentProvider userAgentProvider;
private HttpClient httpClient;

public CtpClient(
IHttpClientFactory httpClientFactory,
IHttpApiCommandFactory httpApiCommandFactory,
ISerializerService serializerService,
IUserAgentProvider userAgentProvider)
ISerializerService serializerService)
{
this.httpClientFactory = httpClientFactory;
this.serializerService = serializerService;
this.httpApiCommandFactory = httpApiCommandFactory;
this.userAgentProvider = userAgentProvider;
}

public string Name { get; set; } = DefaultClientNames.Api;

private HttpClient HttpClient
{
get
{
if (this.httpClient == null)
{
this.httpClient = this.httpClientFactory.CreateClient(this.Name);
this.httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(this.userAgentProvider.UserAgent);
}

return this.httpClient;
}
}
private HttpClient HttpClient => this.httpClient ?? (this.httpClient = this.httpClientFactory.CreateClient(this.Name));

public async Task<T> ExecuteAsync<T>(Command<T> command)
{
Expand Down
25 changes: 25 additions & 0 deletions commercetools.Sdk/commercetools.Sdk.HttpApi/CtpClientFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System.Net.Http;
using commercetools.Sdk.Client;
using commercetools.Sdk.Serialization;

namespace commercetools.Sdk.HttpApi
{
public class CtpClientFactory : ICtpClientFactory
{
private readonly IHttpClientFactory clientFactory;
private readonly IHttpApiCommandFactory httpApiCommandFactory;
private readonly ISerializerService serializerService;

public CtpClientFactory(IHttpClientFactory clientFactory, IHttpApiCommandFactory httpApiCommandFactory, ISerializerService serializerService)
{
this.clientFactory = clientFactory;
this.httpApiCommandFactory = httpApiCommandFactory;
this.serializerService = serializerService;
}

public IClient Create(string name)
{
return new CtpClient(clientFactory, httpApiCommandFactory, serializerService) { Name = name };
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ public static class DependencyInjectionSetup
{
public static IDictionary<string, IHttpClientBuilder> UseHttpApi(this IServiceCollection services, IConfiguration configuration, IDictionary<string, TokenFlow> clients)
{
services.UseHttpApiDefaults();

if (clients.Count() == 1)
{
return services.UseSingleClient(configuration, clients.First().Key, clients.First().Value);
Expand All @@ -34,7 +36,7 @@ public static IDictionary<string, IHttpClientBuilder> UseHttpApi(this IServiceCo

private static IDictionary<string, IHttpClientBuilder> UseMultipleClients(this IServiceCollection services, IConfiguration configuration, IDictionary<string, TokenFlow> clients)
{
services.UseHttpApiDefaults();
services.AddSingleton<ICtpClientFactory, CtpClientFactory>();
var builders = new ConcurrentDictionary<string, IHttpClientBuilder>();
foreach (KeyValuePair<string, TokenFlow> client in clients)
{
Expand All @@ -45,19 +47,19 @@ private static IDictionary<string, IHttpClientBuilder> UseMultipleClients(this I
Validator.ValidateObject(clientConfiguration, new ValidationContext(clientConfiguration), true);

builders.TryAdd(clientName, services.SetupClient(clientName, clientConfiguration, tokenFlow));
services.AddSingleton<IClient>(c => new CtpClient(c.GetService<IHttpClientFactory>(), c.GetService<IHttpApiCommandFactory>(), c.GetService<ISerializerService>(), c.GetService<IUserAgentProvider>()) { Name = clientName });
services.AddSingleton(c => c.GetService<ICtpClientFactory>().Create(clientName));
}

return builders;
}

private static IDictionary<string, IHttpClientBuilder> UseSingleClient(this IServiceCollection services, IConfiguration configuration, string clientName, TokenFlow tokenFlow)
{
services.AddSingleton<ICtpClientFactory, CtpClientFactory>();
IClientConfiguration clientConfiguration = configuration.GetSection(clientName).Get<ClientConfiguration>();
Validator.ValidateObject(clientConfiguration, new ValidationContext(clientConfiguration), true);

services.UseHttpApiDefaults();
services.AddSingleton<IClient>(c => new CtpClient(c.GetService<IHttpClientFactory>(), c.GetService<IHttpApiCommandFactory>(), c.GetService<ISerializerService>(), c.GetService<IUserAgentProvider>()) { Name = clientName });
services.AddSingleton(c => c.GetService<ICtpClientFactory>().Create(clientName));

var builders = new ConcurrentDictionary<string, IHttpClientBuilder>();
builders.TryAdd(clientName, services.SetupClient(clientName, clientConfiguration, tokenFlow));
Expand All @@ -68,8 +70,12 @@ private static IDictionary<string, IHttpClientBuilder> UseSingleClient(this ISer
private static IHttpClientBuilder SetupClient(this IServiceCollection services, string clientName, IClientConfiguration clientConfiguration, TokenFlow tokenFlow)
{
var httpClientBuilder = services.AddHttpClient(clientName)
.ConfigureHttpClient(client =>
client.BaseAddress = new Uri(clientConfiguration.ApiBaseAddress + clientConfiguration.ProjectKey + "/"))
.ConfigureHttpClient((c, client) =>
{
client.BaseAddress =
new Uri(clientConfiguration.ApiBaseAddress + clientConfiguration.ProjectKey + "/");
client.DefaultRequestHeaders.UserAgent.ParseAdd(c.GetService<IUserAgentProvider>().UserAgent);
})
.AddHttpMessageHandler(c =>
{
var providers = c.GetServices<ITokenProvider>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using commercetools.Sdk.Client;

namespace commercetools.Sdk.HttpApi
{
public interface ICtpClientFactory
{
IClient Create(string name);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ private static IDictionary<string, IHttpClientBuilder> UseMultipleClients(this C
{
var collection = new ServiceCollection();
services.UseHttpApiDefaults();
services.Register<ICtpClientFactory>(() => new CtpClientFactory(collection.BuildServiceProvider().GetService<IHttpClientFactory>(), services.GetService<IHttpApiCommandFactory>(), services.GetService<ISerializerService>()), Lifestyle.Singleton);

var builders = new ConcurrentDictionary<string, IHttpClientBuilder>();
var clientBuilders = new List<Registration>();
Expand All @@ -156,7 +157,7 @@ private static IDictionary<string, IHttpClientBuilder> UseMultipleClients(this C

builders.TryAdd(clientName, services.SetupClient(collection, clientName, clientConfiguration, tokenFlow));

clientBuilders.Add(Lifestyle.Singleton.CreateRegistration(() => new CtpClient(collection.BuildServiceProvider().GetService<IHttpClientFactory>(), services.GetService<IHttpApiCommandFactory>(), services.GetService<ISerializerService>(), services.GetService<IUserAgentProvider>()) { Name = clientName }, services));
clientBuilders.Add(Lifestyle.Singleton.CreateRegistration(() => services.GetService<ICtpClientFactory>().Create(clientName), services));
}
services.RegisterCollection<IClient>(clientBuilders);

Expand Down Expand Up @@ -189,15 +190,17 @@ private static IDictionary<string, IHttpClientBuilder> UseSingleClient(this Cont
{
var collection = new ServiceCollection();
services.UseHttpApiDefaults();
services.Register<ICtpClientFactory>(() => new CtpClientFactory(collection.BuildServiceProvider().GetService<IHttpClientFactory>(), services.GetService<IHttpApiCommandFactory>(), services.GetService<ISerializerService>()), Lifestyle.Singleton);

var configurationSection = configuration.GetSection(clientName);
IClientConfiguration clientConfiguration = configurationSection.Get<ClientConfiguration>();
Validator.ValidateObject(clientConfiguration, new ValidationContext(clientConfiguration), true);

var builders = new ConcurrentDictionary<string, IHttpClientBuilder>();
builders.TryAdd(clientName, services.SetupClient(collection, clientName, clientConfiguration, tokenFlow));

services.Register<IClient>(() => new CtpClient(collection.BuildServiceProvider().GetService<IHttpClientFactory>(), services.GetService<IHttpApiCommandFactory>(), services.GetService<ISerializerService>(), services.GetService<IUserAgentProvider>()) { Name = clientName }, Lifestyle.Singleton);


services.Register(() => services.GetService<ICtpClientFactory>().Create(clientName), Lifestyle.Singleton);

collection.AddHttpClient(DefaultClientNames.Authorization);
services.UseTokenProviders(collection.BuildServiceProvider().GetService<IHttpClientFactory>());
Expand All @@ -209,7 +212,11 @@ private static IHttpClientBuilder SetupClient(this Container services, IServiceC
{
var httpClientBuilder = collection.AddHttpClient(clientName)
.ConfigureHttpClient(client =>
client.BaseAddress = new Uri(clientConfiguration.ApiBaseAddress + clientConfiguration.ProjectKey + "/"))
{
client.BaseAddress =
new Uri(clientConfiguration.ApiBaseAddress + clientConfiguration.ProjectKey + "/");
client.DefaultRequestHeaders.UserAgent.ParseAdd(services.GetService<IUserAgentProvider>().UserAgent);
})
.AddHttpMessageHandler(c =>
{
var providers = services.GetAllInstances<ITokenProvider>();
Expand Down