diff --git a/README.md b/README.md
index b458205..cabc416 100755
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@
### Mac
数据库: ~/Library/Application Support/Resonance/Databases
-偏好设置: ~/Library/Preferences/com.oces.Resonance.plist
+偏好设置: ~/Library/Preferences/com.oces.Resonance.json
缓存数据: ~/Library/Caches/com.oces.Resonance
### Windows
diff --git a/src/Core/Database.cs b/src/Core/Database.cs
index 74e8136..1d17671 100755
--- a/src/Core/Database.cs
+++ b/src/Core/Database.cs
@@ -13,7 +13,7 @@ public static class Database
/// 数据库连接
internal static IDbConnection GetConnection(string dbName = "default")
{
- string connectionString = $"Data Source={dbName}.rdb;Version=3;";
+ string connectionString = $"Data Source={Path.Combine(PreferencesManager.GetDefaultDatabasePath(), dbName)}.rdb;Version=3;";
return new SQLiteConnection(connectionString);
}
diff --git a/src/Core/Preferences.cs b/src/Core/Preferences.cs
index 6da8bb0..0c10bc3 100644
--- a/src/Core/Preferences.cs
+++ b/src/Core/Preferences.cs
@@ -1,108 +1,10 @@
-using Newtonsoft.Json;
-
namespace OCES.Resonance.Core;
///
-/// 应用偏好设置,单例模式,负责平台路径解析与 JSON 持久化。
+/// 应用偏好设置数据模型,由 统一管理生命周期。
///
public class Preferences
{
- private static readonly Lazy _instance = new(() => new Preferences());
-
- /// 单例访问入口
- public static Preferences Instance
- {
- get { return _instance.Value; }
- }
-
/// 数据库文件存放目录
public string DatabasePath { get; set; } = string.Empty;
-
- /// 偏好设置 JSON 文件的完整路径
- public string PreferencesPath { get; set; } = string.Empty;
-
- ///
- /// 私有构造函数 —— 根据运行时平台设置 和 。
- /// JSON 反序列化时也会调用此构造函数,随后由 JSON 属性覆盖路径值。
- ///
- [JsonConstructor]
- Preferences()
- {
- if (OperatingSystem.IsMacOS())
- {
- string home = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
- DatabasePath = Path.Combine(home, "OCES","Resonance", "Databases");
- PreferencesPath = Path.Combine(home, "Library", "Preferences", "com.oces.Resonance.json");
- }
- else if (OperatingSystem.IsWindows())
- {
- string localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
- string roamingAppData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
- DatabasePath = Path.Combine(localAppData, "OCES", "Resonance", "Databases");
- PreferencesPath = Path.Combine(roamingAppData, "OCES", "Resonance", "preferences.json");
- }
- else if (OperatingSystem.IsLinux())
- {
- string home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
- string xdgDataHome = Environment.GetEnvironmentVariable("XDG_DATA_HOME")
- ?? Path.Combine(home, ".local", "share");
- string xdgConfigHome = Environment.GetEnvironmentVariable("XDG_CONFIG_HOME")
- ?? Path.Combine(home, ".config");
- DatabasePath = Path.Combine(xdgDataHome, "Resonance", "Databases");
- PreferencesPath = Path.Combine(xdgConfigHome, "Resonance", "preferences.json");
- }
- }
-
- ///
- /// 将传入的 实例序列化为 JSON 文件,保存到 。
- ///
- /// 待序列化的偏好设置实例
- /// 成功返回 true,失败返回 false
- public bool Serialize(Preferences preferences)
- {
- try
- {
- string? directory = Path.GetDirectoryName(PreferencesPath);
- if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
- {
- Directory.CreateDirectory(directory);
- }
-
- string json = JsonConvert.SerializeObject(preferences, Formatting.Indented);
- File.WriteAllText(PreferencesPath, json);
- return true;
- }
- catch
- {
- //调用房根据自己的情况,自己处理接到false该怎么办。
- return false;
- }
- }
-
- ///
- /// 从指定路径读取 JSON 文件并反序列化为 实例。
- ///
- /// JSON 文件的完整路径
- /// 反序列化成功返回 Preferences 实例,失败返回 null
- public Preferences? Deserialize(string preferencesPath)
- {
- try
- {
- if (!File.Exists(preferencesPath))
- {
- return null;
- }
-
- string json = File.ReadAllText(preferencesPath);
- JsonSerializerSettings settings = new()
- {
- ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor,
- };
- return JsonConvert.DeserializeObject(json, settings);
- }
- catch
- {
- return null;
- }
- }
}
diff --git a/src/Core/PreferencesManager.cs b/src/Core/PreferencesManager.cs
new file mode 100644
index 0000000..58d04b8
--- /dev/null
+++ b/src/Core/PreferencesManager.cs
@@ -0,0 +1,150 @@
+using Newtonsoft.Json;
+
+namespace OCES.Resonance.Core;
+
+///
+/// 偏好设置管理器,负责平台路径解析、JSON 持久化以及 实例的生命周期管理。
+///
+public static class PreferencesManager
+{
+ /// 当前活动的偏好设置实例, 调用前为 null
+ public static Preferences? CurrentPreferences { get; set; }
+
+ ///
+ /// 加载偏好设置。先尝试从硬盘反序列化;若文件不存在则创建带平台默认路径的新实例。
+ ///
+ public static void Load()
+ {
+ string preferencesPath = GetDefaultPreferencesPath();
+
+ // 尝试从硬盘加载
+ Preferences? loaded = Deserialize(preferencesPath);
+ if (loaded != null)
+ {
+ CurrentPreferences = loaded;
+ return;
+ }
+
+ // 文件不存在或反序列化失败 → 创建默认实例
+ CurrentPreferences = new Preferences
+ {
+ DatabasePath = GetDefaultDatabasePath()
+ };
+
+ // 立即落盘,确保下次启动能直接读取
+ Serialize(CurrentPreferences);
+ }
+
+ ///
+ /// 将当前 序列化到硬盘。
+ ///
+ public static void Save()
+ {
+ if (CurrentPreferences == null) return;
+ Serialize(CurrentPreferences);
+ }
+
+ ///
+ /// 根据运行时平台返回数据库文件存放目录。
+ ///
+ public static string GetDefaultDatabasePath()
+ {
+ if (OperatingSystem.IsMacOS())
+ {
+ string library = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
+ return Path.Combine(library, "OCES", "Resonance", "Databases");
+ }
+
+ if (OperatingSystem.IsWindows())
+ {
+ string localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
+ return Path.Combine(localAppData, "OCES", "Resonance", "Databases");
+ }
+
+ if (OperatingSystem.IsLinux())
+ {
+ string home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
+ string xdgDataHome = Environment.GetEnvironmentVariable("XDG_DATA_HOME")
+ ?? Path.Combine(home, ".local", "share");
+ return Path.Combine(xdgDataHome, "Resonance", "Databases");
+ }
+
+ return string.Empty;
+ }
+
+ ///
+ /// 根据运行时平台返回偏好设置 JSON 文件的完整路径。
+ ///
+ public static string GetDefaultPreferencesPath()
+ {
+ if (OperatingSystem.IsMacOS())
+ {
+ string library = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
+ return Path.Combine(library, "Preferences", "com.oces.Resonance.json");
+ }
+
+ if (OperatingSystem.IsWindows())
+ {
+ string roamingAppData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
+ return Path.Combine(roamingAppData, "OCES", "Resonance", "preferences.json");
+ }
+
+ if (OperatingSystem.IsLinux())
+ {
+ string home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
+ string xdgConfigHome = Environment.GetEnvironmentVariable("XDG_CONFIG_HOME")
+ ?? Path.Combine(home, ".config");
+ return Path.Combine(xdgConfigHome, "Resonance", "preferences.json");
+ }
+
+ return string.Empty;
+ }
+
+ ///
+ /// 将 实例序列化为 JSON 文件,保存到平台默认偏好设置路径。
+ ///
+ /// 成功返回 true,失败返回 false
+ static bool Serialize(Preferences preferences)
+ {
+ try
+ {
+ string path = GetDefaultPreferencesPath();
+ string? directory = Path.GetDirectoryName(path);
+ if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
+ {
+ Directory.CreateDirectory(directory);
+ }
+
+ string json = JsonConvert.SerializeObject(preferences, Formatting.Indented);
+ File.WriteAllText(path, json);
+ return true;
+ }
+ catch
+ {
+ // 调用方根据自己的情况处理 false
+ return false;
+ }
+ }
+
+ ///
+ /// 从指定路径读取 JSON 文件并反序列化为 实例。
+ ///
+ /// 反序列化成功返回实例,失败返回 null
+ static Preferences? Deserialize(string preferencesPath)
+ {
+ try
+ {
+ if (!File.Exists(preferencesPath))
+ {
+ return null;
+ }
+
+ string json = File.ReadAllText(preferencesPath);
+ return JsonConvert.DeserializeObject(json);
+ }
+ catch
+ {
+ return null;
+ }
+ }
+}