littleshop/LittleShop.Client/Extensions/ServiceCollectionExtensions.cs
SysAdmin d31c0b4aeb CI/CD: Add GitLab CI/CD pipeline for Hostinger deployment
- Updated .gitlab-ci.yml with complete build, test, and deploy stages
- Added authentication redirect fix in Program.cs (302 redirect for admin routes)
- Fixed Cookie vs Bearer authentication conflict for admin panel
- Configure pipeline to build from .NET 9.0 source
- Deploy to Hostinger VPS with proper environment variables
- Include rollback capability for production deployments

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-01 13:10:48 +01:00

159 lines
6.9 KiB
C#

using System.Net;
using LittleShop.Client.Configuration;
using LittleShop.Client.Http;
using LittleShop.Client.Services;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace LittleShop.Client.Extensions;
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddLittleShopClient(
this IServiceCollection services,
Action<LittleShopClientOptions>? configureOptions = null,
bool useTorProxy = false,
int torSocksPort = 9050)
{
// Configure options
if (configureOptions != null)
{
services.Configure(configureOptions);
}
else
{
services.Configure<LittleShopClientOptions>(options => { });
}
// Register HTTP handlers
services.AddTransient<RetryPolicyHandler>();
services.AddTransient<ErrorHandlingMiddleware>();
// Helper function to configure SOCKS5 proxy if TOR is enabled
Func<IServiceProvider, HttpMessageHandler> createHandler = (serviceProvider) =>
{
if (useTorProxy)
{
var loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
var logger = loggerFactory.CreateLogger("LittleShop.Client.TorProxy");
var proxyUri = $"socks5://127.0.0.1:{torSocksPort}";
logger.LogInformation("LittleShop.Client: Configuring SOCKS5 proxy at {ProxyUri}", proxyUri);
return new SocketsHttpHandler
{
Proxy = new WebProxy(proxyUri)
{
BypassProxyOnLocal = false,
UseDefaultCredentials = false
},
UseProxy = true,
AllowAutoRedirect = false,
PooledConnectionLifetime = TimeSpan.FromMinutes(5),
PooledConnectionIdleTimeout = TimeSpan.FromMinutes(2)
};
}
else
{
return new SocketsHttpHandler();
}
};
// Register main HTTP client
services.AddHttpClient<IAuthenticationService, AuthenticationService>((serviceProvider, client) =>
{
var options = serviceProvider.GetRequiredService<IOptions<LittleShopClientOptions>>().Value;
client.BaseAddress = new Uri(options.BaseUrl);
client.Timeout = TimeSpan.FromSeconds(options.TimeoutSeconds);
client.DefaultRequestHeaders.Add("Accept", "application/json");
})
.ConfigurePrimaryHttpMessageHandler(createHandler)
.AddHttpMessageHandler<ErrorHandlingMiddleware>()
.AddHttpMessageHandler(serviceProvider =>
{
var logger = serviceProvider.GetRequiredService<ILogger<RetryPolicyHandler>>();
var options = serviceProvider.GetRequiredService<IOptions<LittleShopClientOptions>>().Value;
return new RetryPolicyHandler(logger, options.MaxRetryAttempts);
});
services.AddHttpClient<ICatalogService, CatalogService>((serviceProvider, client) =>
{
var options = serviceProvider.GetRequiredService<IOptions<LittleShopClientOptions>>().Value;
client.BaseAddress = new Uri(options.BaseUrl);
client.Timeout = TimeSpan.FromSeconds(options.TimeoutSeconds);
client.DefaultRequestHeaders.Add("Accept", "application/json");
})
.ConfigurePrimaryHttpMessageHandler(createHandler)
.AddHttpMessageHandler<ErrorHandlingMiddleware>()
.AddHttpMessageHandler(serviceProvider =>
{
var logger = serviceProvider.GetRequiredService<ILogger<RetryPolicyHandler>>();
var options = serviceProvider.GetRequiredService<IOptions<LittleShopClientOptions>>().Value;
return new RetryPolicyHandler(logger, options.MaxRetryAttempts);
});
services.AddHttpClient<IOrderService, OrderService>((serviceProvider, client) =>
{
var options = serviceProvider.GetRequiredService<IOptions<LittleShopClientOptions>>().Value;
client.BaseAddress = new Uri(options.BaseUrl);
client.Timeout = TimeSpan.FromSeconds(options.TimeoutSeconds);
client.DefaultRequestHeaders.Add("Accept", "application/json");
})
.ConfigurePrimaryHttpMessageHandler(createHandler)
.AddHttpMessageHandler<ErrorHandlingMiddleware>()
.AddHttpMessageHandler(serviceProvider =>
{
var logger = serviceProvider.GetRequiredService<ILogger<RetryPolicyHandler>>();
var options = serviceProvider.GetRequiredService<IOptions<LittleShopClientOptions>>().Value;
return new RetryPolicyHandler(logger, options.MaxRetryAttempts);
});
services.AddHttpClient<ICustomerService, CustomerService>((serviceProvider, client) =>
{
var options = serviceProvider.GetRequiredService<IOptions<LittleShopClientOptions>>().Value;
client.BaseAddress = new Uri(options.BaseUrl);
client.Timeout = TimeSpan.FromSeconds(options.TimeoutSeconds);
client.DefaultRequestHeaders.Add("Accept", "application/json");
})
.ConfigurePrimaryHttpMessageHandler(createHandler)
.AddHttpMessageHandler<ErrorHandlingMiddleware>()
.AddHttpMessageHandler(serviceProvider =>
{
var logger = serviceProvider.GetRequiredService<ILogger<RetryPolicyHandler>>();
var options = serviceProvider.GetRequiredService<IOptions<LittleShopClientOptions>>().Value;
return new RetryPolicyHandler(logger, options.MaxRetryAttempts);
});
services.AddHttpClient<IMessageService, MessageService>((serviceProvider, client) =>
{
var options = serviceProvider.GetRequiredService<IOptions<LittleShopClientOptions>>().Value;
client.BaseAddress = new Uri(options.BaseUrl);
client.Timeout = TimeSpan.FromSeconds(options.TimeoutSeconds);
client.DefaultRequestHeaders.Add("Accept", "application/json");
})
.ConfigurePrimaryHttpMessageHandler(createHandler)
.AddHttpMessageHandler<ErrorHandlingMiddleware>()
.AddHttpMessageHandler(serviceProvider =>
{
var logger = serviceProvider.GetRequiredService<ILogger<RetryPolicyHandler>>();
var options = serviceProvider.GetRequiredService<IOptions<LittleShopClientOptions>>().Value;
return new RetryPolicyHandler(logger, options.MaxRetryAttempts);
});
// Register the main client
services.AddScoped<ILittleShopClient, LittleShopClient>();
return services;
}
public static IServiceCollection AddLittleShopClient(
this IServiceCollection services,
string baseUrl)
{
return services.AddLittleShopClient(options =>
{
options.BaseUrl = baseUrl;
});
}
}