Added SettingsLocker service and implementation

This commit is contained in:
Thorsten Sommer 2025-06-01 20:46:33 +02:00
parent f4b203863c
commit ed006f3a4b
Signed by: tsommer
GPG Key ID: 371BBA77A02C0108
3 changed files with 80 additions and 0 deletions

View File

@ -126,6 +126,7 @@ internal sealed class Program
builder.Services.AddSingleton<SettingsManager>(); builder.Services.AddSingleton<SettingsManager>();
builder.Services.AddSingleton<ThreadSafeRandom>(); builder.Services.AddSingleton<ThreadSafeRandom>();
builder.Services.AddSingleton<DataSourceService>(); builder.Services.AddSingleton<DataSourceService>();
builder.Services.AddSingleton<SettingsLocker>();
builder.Services.AddTransient<HTMLParser>(); builder.Services.AddTransient<HTMLParser>();
builder.Services.AddTransient<AgentDataSourceSelection>(); builder.Services.AddTransient<AgentDataSourceSelection>();
builder.Services.AddTransient<AgentRetrievalContextValidation>(); builder.Services.AddTransient<AgentRetrievalContextValidation>();

View File

@ -0,0 +1,78 @@
using System.Linq.Expressions;
namespace AIStudio.Settings;
public sealed class SettingsLocker
{
private static readonly ILogger<SettingsLocker> LOGGER = Program.LOGGER_FACTORY.CreateLogger<SettingsLocker>();
private readonly Dictionary<string, Dictionary<string, Guid>> lockedProperties = new();
public void Register<T>(Expression<Func<T, object>> propertyExpression, Guid configurationPluginId)
{
var memberExpression = GetMemberExpression(propertyExpression);
var className = typeof(T).Name;
var propertyName = memberExpression.Member.Name;
if (!this.lockedProperties.ContainsKey(className))
this.lockedProperties[className] = [];
this.lockedProperties[className].TryAdd(propertyName, configurationPluginId);
}
public void Remove<T>(Expression<Func<T, object>> propertyExpression)
{
var memberExpression = GetMemberExpression(propertyExpression);
var className = typeof(T).Name;
var propertyName = memberExpression.Member.Name;
if (this.lockedProperties.TryGetValue(className, out var props))
{
if (props.Remove(propertyName))
{
// If the property was removed, check if the class has no more locked properties:
if (props.Count == 0)
this.lockedProperties.Remove(className);
}
}
}
public Guid GetConfigurationPluginId<T>(Expression<Func<T, object>> propertyExpression)
{
var memberExpression = GetMemberExpression(propertyExpression);
var className = typeof(T).Name;
var propertyName = memberExpression.Member.Name;
if (this.lockedProperties.TryGetValue(className, out var props) && props.TryGetValue(propertyName, out var configurationPluginId))
return configurationPluginId;
// No configuration plugin ID found for this property:
return Guid.Empty;
}
public bool IsLocked<T>(Expression<Func<T, object>> propertyExpression)
{
var memberExpression = GetMemberExpression(propertyExpression);
var className = typeof(T).Name;
var propertyName = memberExpression.Member.Name;
return this.lockedProperties.TryGetValue(className, out var props) && props.ContainsKey(propertyName);
}
private static MemberExpression GetMemberExpression<T>(Expression<Func<T, object>> expression)
{
switch (expression.Body)
{
// Case for value types, which are wrapped in UnaryExpression:
case UnaryExpression { NodeType: ExpressionType.Convert } unaryExpression:
return (MemberExpression)unaryExpression.Operand;
// Case for reference types, which are directly MemberExpressions:
case MemberExpression memberExpression:
return memberExpression;
default:
LOGGER.LogError($"Expression '{expression}' is not a valid property expression.");
throw new ArgumentException($"Expression '{expression}' is not a valid property expression.", nameof(expression));
}
}
}

View File

@ -6,6 +6,7 @@ public static partial class PluginFactory
{ {
private static readonly ILogger LOG = Program.LOGGER_FACTORY.CreateLogger(nameof(PluginFactory)); private static readonly ILogger LOG = Program.LOGGER_FACTORY.CreateLogger(nameof(PluginFactory));
private static readonly SettingsManager SETTINGS_MANAGER = Program.SERVICE_PROVIDER.GetRequiredService<SettingsManager>(); private static readonly SettingsManager SETTINGS_MANAGER = Program.SERVICE_PROVIDER.GetRequiredService<SettingsManager>();
private static readonly SettingsLocker SETTINGS_LOCKER = Program.SERVICE_PROVIDER.GetRequiredService<SettingsLocker>();
private static bool IS_INITIALIZED; private static bool IS_INITIALIZED;
private static string DATA_DIR = string.Empty; private static string DATA_DIR = string.Empty;