Add flagsmith

This commit is contained in:
2025-12-11 19:22:54 +07:00
parent 65d00c0b9a
commit 35df25915f
6 changed files with 187 additions and 2 deletions

View File

@@ -0,0 +1,122 @@
using Flagsmith;
using Managing.Application.Abstractions.Services;
using Microsoft.Extensions.Logging;
namespace Managing.Application.Shared;
/// <summary>
/// Configuration settings for Flagsmith
/// </summary>
public class FlagsmithSettings
{
public string ApiKey { get; set; } = string.Empty;
/// <summary>
/// API URL for self-hosted Flagsmith instance (required).
/// </summary>
public string ApiUrl { get; set; } = string.Empty;
}
/// <summary>
/// Service for managing feature flags using Flagsmith
/// </summary>
public class FlagsmithService : IFlagsmithService
{
private readonly FlagsmithClient _flagsmithClient;
private readonly ILogger<FlagsmithService> _logger;
public FlagsmithService(FlagsmithClient flagsmithClient, ILogger<FlagsmithService> logger)
{
_flagsmithClient = flagsmithClient ?? throw new ArgumentNullException(nameof(flagsmithClient));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public async Task<IFlagsmithFlags> GetIdentityFlagsAsync(string identity)
{
if (string.IsNullOrWhiteSpace(identity))
{
throw new ArgumentException("Identity cannot be null or empty", nameof(identity));
}
try
{
var flags = await _flagsmithClient.GetIdentityFlags(identity);
return new FlagsmithFlagsWrapper(flags);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error getting flags for identity {Identity}", identity);
throw;
}
}
public async Task<bool> IsFeatureEnabledAsync(string identity, string featureName)
{
if (string.IsNullOrWhiteSpace(identity))
{
throw new ArgumentException("Identity cannot be null or empty", nameof(identity));
}
if (string.IsNullOrWhiteSpace(featureName))
{
throw new ArgumentException("Feature name cannot be null or empty", nameof(featureName));
}
try
{
var flags = await GetIdentityFlagsAsync(identity);
return await flags.IsFeatureEnabled(featureName);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error checking feature {FeatureName} for identity {Identity}", featureName, identity);
return false; // Default to false on error
}
}
public async Task<string?> GetFeatureValueAsync(string identity, string featureName)
{
if (string.IsNullOrWhiteSpace(identity))
{
throw new ArgumentException("Identity cannot be null or empty", nameof(identity));
}
if (string.IsNullOrWhiteSpace(featureName))
{
throw new ArgumentException("Feature name cannot be null or empty", nameof(featureName));
}
try
{
var flags = await GetIdentityFlagsAsync(identity);
return await flags.GetFeatureValue(featureName);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error getting feature value {FeatureName} for identity {Identity}", featureName, identity);
return null; // Default to null on error
}
}
}
/// <summary>
/// Wrapper for Flagsmith flags to implement IFlagsmithFlags interface
/// </summary>
internal class FlagsmithFlagsWrapper : IFlagsmithFlags
{
private readonly IFlags _flags;
public FlagsmithFlagsWrapper(IFlags flags)
{
_flags = flags ?? throw new ArgumentNullException(nameof(flags));
}
public Task<bool> IsFeatureEnabled(string featureName)
{
return _flags.IsFeatureEnabled(featureName);
}
public Task<string?> GetFeatureValue(string featureName)
{
return _flags.GetFeatureValue(featureName);
}
}