Refactored settings manager access across the project

This commit is contained in:
Thorsten Sommer 2026-06-10 20:29:27 +02:00
parent 0b8b918d68
commit b78837926a
Signed by untrusted user who does not match committer: tsommer
GPG Key ID: 371BBA77A02C0108
11 changed files with 31 additions and 30 deletions

View File

@ -151,7 +151,7 @@ public record ConfigMeta<TClass, TValue> : ConfigMetaBase
/// </summary> /// </summary>
private void Reset() private void Reset()
{ {
var configInstance = this.ConfigSelection.Compile().Invoke(SettingsManager.ConfigurationData); var configInstance = this.ConfigSelection.Compile().Invoke(SettingsManagerAccess.ConfigurationData);
var memberExpression = this.PropertyExpression.GetMemberExpression(); var memberExpression = this.PropertyExpression.GetMemberExpression();
if (memberExpression.Member is System.Reflection.PropertyInfo propertyInfo) if (memberExpression.Member is System.Reflection.PropertyInfo propertyInfo)
propertyInfo.SetValue(configInstance, this.Default); propertyInfo.SetValue(configInstance, this.Default);
@ -163,7 +163,7 @@ public record ConfigMeta<TClass, TValue> : ConfigMetaBase
/// <param name="value">The value to set for the configuration property.</param> /// <param name="value">The value to set for the configuration property.</param>
public void SetValue(TValue value) public void SetValue(TValue value)
{ {
var configInstance = this.ConfigSelection.Compile().Invoke(SettingsManager.ConfigurationData); var configInstance = this.ConfigSelection.Compile().Invoke(SettingsManagerAccess.ConfigurationData);
var memberExpression = this.PropertyExpression.GetMemberExpression(); var memberExpression = this.PropertyExpression.GetMemberExpression();
if (memberExpression.Member is System.Reflection.PropertyInfo propertyInfo) if (memberExpression.Member is System.Reflection.PropertyInfo propertyInfo)
propertyInfo.SetValue(configInstance, value); propertyInfo.SetValue(configInstance, value);
@ -174,7 +174,7 @@ public record ConfigMeta<TClass, TValue> : ConfigMetaBase
/// </summary> /// </summary>
public TValue GetValue() public TValue GetValue()
{ {
var configInstance = this.ConfigSelection.Compile().Invoke(SettingsManager.ConfigurationData); var configInstance = this.ConfigSelection.Compile().Invoke(SettingsManagerAccess.ConfigurationData);
var memberExpression = this.PropertyExpression.GetMemberExpression(); var memberExpression = this.PropertyExpression.GetMemberExpression();
if (memberExpression.Member is System.Reflection.PropertyInfo propertyInfo && propertyInfo.GetValue(configInstance) is TValue value) if (memberExpression.Member is System.Reflection.PropertyInfo propertyInfo && propertyInfo.GetValue(configInstance) is TValue value)
return value; return value;

View File

@ -2,5 +2,5 @@ namespace AIStudio.Settings;
public abstract record ConfigMetaBase : IConfig public abstract record ConfigMetaBase : IConfig
{ {
protected static SettingsManager SettingsManager => Program.SERVICE_PROVIDER.GetRequiredService<SettingsManager>(); protected static SettingsManager SettingsManagerAccess => Program.SERVICE_PROVIDER.GetRequiredService<SettingsManager>();
} }

View File

@ -654,7 +654,7 @@ public static partial class ManagedConfiguration
if (successful) if (successful)
{ {
var configInstance = configSelection.Compile().Invoke(SettingsManager.ConfigurationData); var configInstance = configSelection.Compile().Invoke(SettingsManagerAccess.ConfigurationData);
var currentValue = propertyExpression.Compile().Invoke(configInstance); var currentValue = propertyExpression.Compile().Invoke(configInstance);
var merged = new HashSet<TValue>(currentValue); var merged = new HashSet<TValue>(currentValue);
merged.UnionWith(configuredValue); merged.UnionWith(configuredValue);

View File

@ -9,7 +9,7 @@ namespace AIStudio.Settings;
public static partial class ManagedConfiguration public static partial class ManagedConfiguration
{ {
private static readonly ConcurrentDictionary<string, IConfig> METADATA = new(); private static readonly ConcurrentDictionary<string, IConfig> METADATA = new();
private static SettingsManager SettingsManager => Program.SERVICE_PROVIDER.GetRequiredService<SettingsManager>(); private static SettingsManager SettingsManagerAccess => Program.SERVICE_PROVIDER.GetRequiredService<SettingsManager>();
/// <summary> /// <summary>
/// Attempts to retrieve the configuration metadata for a given configuration selection and /// Attempts to retrieve the configuration metadata for a given configuration selection and
@ -418,19 +418,19 @@ public static partial class ManagedConfiguration
private static bool TryGetEditableDefaultState(string settingName, out ManagedEditableDefaultState editableDefaultState) private static bool TryGetEditableDefaultState(string settingName, out ManagedEditableDefaultState editableDefaultState)
{ {
return SettingsManager.ConfigurationData.ManagedEditableDefaults.TryGetValue(settingName, out editableDefaultState!); return SettingsManagerAccess.ConfigurationData.ManagedEditableDefaults.TryGetValue(settingName, out editableDefaultState!);
} }
private static void SetEditableDefaultState(string settingName, Guid pluginId, string lastAppliedValue) private static void SetEditableDefaultState(string settingName, Guid pluginId, string lastAppliedValue)
{ {
SettingsManager.ConfigurationData.ManagedEditableDefaults[settingName] = new() SettingsManagerAccess.ConfigurationData.ManagedEditableDefaults[settingName] = new()
{ {
ConfigPluginId = pluginId, ConfigPluginId = pluginId,
LastAppliedValue = lastAppliedValue, LastAppliedValue = lastAppliedValue,
}; };
} }
private static bool ClearEditableDefaultState(string settingName) => SettingsManager.ConfigurationData.ManagedEditableDefaults.Remove(settingName); private static bool ClearEditableDefaultState(string settingName) => SettingsManagerAccess.ConfigurationData.ManagedEditableDefaults.Remove(settingName);
private static bool CleanupEditableDefaultState<TClass, TValue>( private static bool CleanupEditableDefaultState<TClass, TValue>(
ConfigMeta<TClass, TValue> configMeta, ConfigMeta<TClass, TValue> configMeta,

View File

@ -26,7 +26,7 @@ public static class ExternalHttpClientTimeout
private static string TB(string fallbackEN) => PluginSystem.I18N.I.T(fallbackEN, typeof(ExternalHttpClientTimeout).Namespace, nameof(ExternalHttpClientTimeout)); private static string TB(string fallbackEN) => PluginSystem.I18N.I.T(fallbackEN, typeof(ExternalHttpClientTimeout).Namespace, nameof(ExternalHttpClientTimeout));
private static readonly Lazy<ILogger> LOGGER = new(() => Program.LOGGER_FACTORY.CreateLogger(nameof(ExternalHttpClientTimeout))); private static readonly Lazy<ILogger> LOGGER = new(() => Program.LOGGER_FACTORY.CreateLogger(nameof(ExternalHttpClientTimeout)));
private static readonly Lazy<SettingsManager> SETTINGS_MANAGER = new(() => Program.SERVICE_PROVIDER.GetRequiredService<SettingsManager>()); private static SettingsManager SettingsManagerAccess => Program.SERVICE_PROVIDER.GetRequiredService<SettingsManager>();
private static readonly Lock CUSTOM_ROOT_CERTIFICATE_LOCK = new(); private static readonly Lock CUSTOM_ROOT_CERTIFICATE_LOCK = new();
private static CustomRootCertificateCache? CUSTOM_ROOT_CERTIFICATE_CACHE; private static CustomRootCertificateCache? CUSTOM_ROOT_CERTIFICATE_CACHE;
@ -91,7 +91,7 @@ public static class ExternalHttpClientTimeout
private static TimeSpan GetTimeout() private static TimeSpan GetTimeout()
{ {
var seconds = SETTINGS_MANAGER.Value.ConfigurationData.App.HttpClientTimeoutSeconds; var seconds = SettingsManagerAccess.ConfigurationData.App.HttpClientTimeoutSeconds;
if (seconds <= 0) if (seconds <= 0)
seconds = DEFAULT_HTTP_CLIENT_TIMEOUT_SECONDS; seconds = DEFAULT_HTTP_CLIENT_TIMEOUT_SECONDS;
@ -129,11 +129,11 @@ public static class ExternalHttpClientTimeout
var enabled = TryParseBooleanEnvironmentValue(envEnabled, out var parsedEnvEnabled) var enabled = TryParseBooleanEnvironmentValue(envEnabled, out var parsedEnvEnabled)
? parsedEnvEnabled ? parsedEnvEnabled
: SETTINGS_MANAGER.Value.ConfigurationData.App.ExternalHttpCustomRootCertificatesEnabled; : SettingsManagerAccess.ConfigurationData.App.ExternalHttpCustomRootCertificatesEnabled;
var bundlePath = !string.IsNullOrWhiteSpace(envBundlePath) var bundlePath = !string.IsNullOrWhiteSpace(envBundlePath)
? envBundlePath.Trim() ? envBundlePath.Trim()
: SETTINGS_MANAGER.Value.ConfigurationData.App.ExternalHttpCustomRootCertificateBundlePath.Trim(); : SettingsManagerAccess.ConfigurationData.App.ExternalHttpCustomRootCertificateBundlePath.Trim();
var allowedHostPatterns = ReadAllowedHostPatterns(envAllowedHosts); var allowedHostPatterns = ReadAllowedHostPatterns(envAllowedHosts);
var source = ReadCustomRootCertificateConfigurationSource(envEnabled, envBundlePath, envAllowedHosts); var source = ReadCustomRootCertificateConfigurationSource(envEnabled, envBundlePath, envAllowedHosts);
@ -158,7 +158,7 @@ public static class ExternalHttpClientTimeout
{ {
IEnumerable<string> rawPatterns = !string.IsNullOrWhiteSpace(envAllowedHosts) IEnumerable<string> rawPatterns = !string.IsNullOrWhiteSpace(envAllowedHosts)
? envAllowedHosts.Split([';', ','], StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries) ? envAllowedHosts.Split([';', ','], StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
: SETTINGS_MANAGER.Value.ConfigurationData.App.ExternalHttpCustomRootCertificateAllowedHosts; : SettingsManagerAccess.ConfigurationData.App.ExternalHttpCustomRootCertificateAllowedHosts;
var patterns = new HashSet<string>(StringComparer.OrdinalIgnoreCase); var patterns = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
foreach (var rawPattern in rawPatterns) foreach (var rawPattern in rawPatterns)

View File

@ -9,7 +9,7 @@ namespace AIStudio.Tools.PluginSystem;
public sealed class PluginConfiguration(bool isInternal, LuaState state, PluginType type) : PluginBase(isInternal, state, type) public sealed class PluginConfiguration(bool isInternal, LuaState state, PluginType type) : PluginBase(isInternal, state, type)
{ {
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(PluginConfiguration).Namespace, nameof(PluginConfiguration)); private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(PluginConfiguration).Namespace, nameof(PluginConfiguration));
private static SettingsManager SettingsManager => Program.SERVICE_PROVIDER.GetRequiredService<SettingsManager>(); private static SettingsManager SettingsManagerAccess => Program.SERVICE_PROVIDER.GetRequiredService<SettingsManager>();
private static readonly ILogger LOG = Program.LOGGER_FACTORY.CreateLogger(nameof(PluginConfiguration)); private static readonly ILogger LOG = Program.LOGGER_FACTORY.CreateLogger(nameof(PluginConfiguration));
private List<PluginConfigurationObject> configObjects = []; private List<PluginConfigurationObject> configObjects = [];
@ -41,7 +41,7 @@ public sealed class PluginConfiguration(bool isInternal, LuaState state, PluginT
await StoreEnterpriseApiKeysAsync(); await StoreEnterpriseApiKeysAsync();
await StoreEnterpriseSecretsAsync(); await StoreEnterpriseSecretsAsync();
await SettingsManager.StoreSettings(); await SettingsManagerAccess.StoreSettings();
await MessageBus.INSTANCE.SendMessage<bool>(null, Event.CONFIGURATION_CHANGED); await MessageBus.INSTANCE.SendMessage<bool>(null, Event.CONFIGURATION_CHANGED);
} }
} }

View File

@ -14,8 +14,9 @@ namespace AIStudio.Tools.PluginSystem;
/// </summary> /// </summary>
public sealed record PluginConfigurationObject public sealed record PluginConfigurationObject
{ {
private static readonly RustService RUST_SERVICE = Program.SERVICE_PROVIDER.GetRequiredService<RustService>(); private static RustService RustService => Program.SERVICE_PROVIDER.GetRequiredService<RustService>();
private static SettingsManager SettingsManager => Program.SERVICE_PROVIDER.GetRequiredService<SettingsManager>(); private static SettingsManager SettingsManagerAccess => Program.SERVICE_PROVIDER.GetRequiredService<SettingsManager>();
private static ThreadSafeRandom Rng => Program.SERVICE_PROVIDER.GetRequiredService<ThreadSafeRandom>();
private static readonly ILogger LOG = Program.LOGGER_FACTORY.CreateLogger<PluginConfigurationObject>(); private static readonly ILogger LOG = Program.LOGGER_FACTORY.CreateLogger<PluginConfigurationObject>();
/// <summary> /// <summary>
@ -91,7 +92,7 @@ public sealed record PluginConfigurationObject
return false; return false;
} }
var localSettingsManager = SettingsManager; var localSettingsManager = SettingsManagerAccess;
var storedObjects = configObjectSelection.Compile()(localSettingsManager.ConfigurationData); var storedObjects = configObjectSelection.Compile()(localSettingsManager.ConfigurationData);
var numberObjects = luaTable.ArrayLength; var numberObjects = luaTable.ArrayLength;
ThreadSafeRandom? random = null; ThreadSafeRandom? random = null;
@ -151,7 +152,7 @@ public sealed record PluginConfigurationObject
else else
{ {
// Case: The next number could not be incremented, we use a random number // Case: The next number could not be incremented, we use a random number
random ??= new ThreadSafeRandom(); random ??= Rng;
configObject = configObject with { Num = (uint)random.Next(500_000, 1_000_000) }; configObject = configObject with { Num = (uint)random.Next(500_000, 1_000_000) };
storedObjects.Add((TClass)configObject); storedObjects.Add((TClass)configObject);
LOG.LogWarning("The next number for the configuration object '{ConfigObjectName}' (id={ConfigObjectId}) could not be incremented. Using a random number instead (config plugin id: {ConfigPluginId}).", configObject.Name, configObject.Id, configPluginId); LOG.LogWarning("The next number for the configuration object '{ConfigObjectName}' (id={ConfigObjectId}) could not be incremented. Using a random number instead (config plugin id: {ConfigPluginId}).", configObject.Name, configObject.Id, configPluginId);
@ -186,7 +187,7 @@ public sealed record PluginConfigurationObject
return false; return false;
} }
var localSettingsManager = SettingsManager; var localSettingsManager = SettingsManagerAccess;
var storedObjects = localSettingsManager.ConfigurationData.DataSources; var storedObjects = localSettingsManager.ConfigurationData.DataSources;
var numberObjects = luaTable.ArrayLength; var numberObjects = luaTable.ArrayLength;
ThreadSafeRandom? random = null; ThreadSafeRandom? random = null;
@ -231,7 +232,7 @@ public sealed record PluginConfigurationObject
} }
else else
{ {
random ??= new ThreadSafeRandom(); random ??= Rng;
configObject = configObject with { Num = (uint)random.Next(500_000, 1_000_000) }; configObject = configObject with { Num = (uint)random.Next(500_000, 1_000_000) };
storedObjects.Add(configObject); storedObjects.Add(configObject);
LOG.LogWarning("The next number for the data source '{ConfigObjectName}' (id={ConfigObjectId}) could not be incremented. Using a random number instead (config plugin id: {ConfigPluginId}).", configObject.Name, configObject.Id, configPluginId); LOG.LogWarning("The next number for the data source '{ConfigObjectName}' (id={ConfigObjectId}) could not be incremented. Using a random number instead (config plugin id: {ConfigPluginId}).", configObject.Name, configObject.Id, configPluginId);
@ -266,7 +267,7 @@ public sealed record PluginConfigurationObject
SecretStoreType? secretStoreType = null, SecretStoreType? secretStoreType = null,
bool deleteSecret = false) where TClass : IConfigurationObject bool deleteSecret = false) where TClass : IConfigurationObject
{ {
var localSettingsManager = SettingsManager; var localSettingsManager = SettingsManagerAccess;
var configuredObjects = configObjectSelection.Compile()(localSettingsManager.ConfigurationData); var configuredObjects = configObjectSelection.Compile()(localSettingsManager.ConfigurationData);
var leftOverObjects = new List<TClass>(); var leftOverObjects = new List<TClass>();
foreach (var configuredObject in configuredObjects) foreach (var configuredObject in configuredObjects)
@ -310,7 +311,7 @@ public sealed record PluginConfigurationObject
// Delete the API key from the OS keyring if the removed object has one: // Delete the API key from the OS keyring if the removed object has one:
if(deleteSecret && item is ISecretId regularSecretId) if(deleteSecret && item is ISecretId regularSecretId)
{ {
var deleteResult = await RUST_SERVICE.DeleteSecret(regularSecretId, secretStoreType ?? SecretStoreType.DATA_SOURCE); var deleteResult = await RustService.DeleteSecret(regularSecretId, secretStoreType ?? SecretStoreType.DATA_SOURCE);
if (deleteResult.Success) if (deleteResult.Success)
LOG.LogInformation($"Successfully deleted secret for removed enterprise object '{item.Name}' from the OS keyring."); LOG.LogInformation($"Successfully deleted secret for removed enterprise object '{item.Name}' from the OS keyring.");
else else
@ -318,7 +319,7 @@ public sealed record PluginConfigurationObject
} }
else if(secretStoreType is not null && item is ISecretId secretId) else if(secretStoreType is not null && item is ISecretId secretId)
{ {
var deleteResult = await RUST_SERVICE.DeleteAPIKey(secretId, secretStoreType.Value); var deleteResult = await RustService.DeleteAPIKey(secretId, secretStoreType.Value);
if (deleteResult.Success) if (deleteResult.Success)
LOG.LogInformation($"Successfully deleted API key for removed enterprise provider '{item.Name}' from the OS keyring."); LOG.LogInformation($"Successfully deleted API key for removed enterprise provider '{item.Name}' from the OS keyring.");
else else

View File

@ -191,7 +191,7 @@ public static partial class PluginFactory
wasConfigurationChanged = true; wasConfigurationChanged = true;
// Check left-over mandatory info acceptances: // Check left-over mandatory info acceptances:
if (SettingsManager.ConfigurationData.MandatoryInformation.RemoveLeftOverAcceptances(GetMandatoryInfos())) if (SettingsManagerAccess.ConfigurationData.MandatoryInformation.RemoveLeftOverAcceptances(GetMandatoryInfos()))
wasConfigurationChanged = true; wasConfigurationChanged = true;
// Check for a preselected provider: // Check for a preselected provider:
@ -285,7 +285,7 @@ public static partial class PluginFactory
if (wasConfigurationChanged) if (wasConfigurationChanged)
{ {
await SettingsManager.StoreSettings(); await SettingsManagerAccess.StoreSettings();
await MessageBus.INSTANCE.SendMessage<bool>(null, Event.CONFIGURATION_CHANGED); await MessageBus.INSTANCE.SendMessage<bool>(null, Event.CONFIGURATION_CHANGED);
} }
} }

View File

@ -64,7 +64,7 @@ public static partial class PluginFactory
try try
{ {
if (availablePlugin.IsInternal || SettingsManager.IsPluginEnabled(availablePlugin) || availablePlugin.Type == PluginType.CONFIGURATION || availablePlugin.Type == PluginType.ASSISTANT) if (availablePlugin.IsInternal || SettingsManagerAccess.IsPluginEnabled(availablePlugin) || availablePlugin.Type == PluginType.CONFIGURATION || availablePlugin.Type == PluginType.ASSISTANT)
if(await Start(availablePlugin, cancellationToken) is { IsValid: true } plugin) if(await Start(availablePlugin, cancellationToken) is { IsValid: true } plugin)
{ {
if (plugin is PluginConfiguration configPlugin) if (plugin is PluginConfiguration configPlugin)

View File

@ -6,7 +6,7 @@ namespace AIStudio.Tools.PluginSystem;
public static partial class PluginFactory 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 SettingsManager SettingsManager => Program.SERVICE_PROVIDER.GetRequiredService<SettingsManager>(); private static SettingsManager SettingsManagerAccess => Program.SERVICE_PROVIDER.GetRequiredService<SettingsManager>();
private static string DATA_DIR = string.Empty; private static string DATA_DIR = string.Empty;
private static string PLUGINS_ROOT = string.Empty; private static string PLUGINS_ROOT = string.Empty;

View File

@ -6,7 +6,7 @@ namespace AIStudio.Tools.RAG;
public static class IRetrievalContextExtensions public static class IRetrievalContextExtensions
{ {
private static readonly ILogger<IRetrievalContext> LOGGER = Program.SERVICE_PROVIDER.GetService<ILogger<IRetrievalContext>>()!; private static readonly ILogger<IRetrievalContext> LOGGER = Program.LOGGER_FACTORY.CreateLogger<IRetrievalContext>();
public static async Task<string> AsMarkdown(this IReadOnlyList<IRetrievalContext> retrievalContexts, StringBuilder? sb = null, CancellationToken token = default) public static async Task<string> AsMarkdown(this IReadOnlyList<IRetrievalContext> retrievalContexts, StringBuilder? sb = null, CancellationToken token = default)
{ {