BasePTModuleSettings.cs
1 // Copyright (c) Microsoft Corporation 2 // The Microsoft Corporation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System; 6 using System.Text.Json; 7 using System.Text.Json.Serialization; 8 9 namespace Microsoft.PowerToys.Settings.UI.Library 10 { 11 /// <summary> 12 /// Base class for all PowerToys module settings. 13 /// </summary> 14 /// <remarks> 15 /// <para><strong>IMPORTANT for Native AOT compatibility:</strong></para> 16 /// <para>When creating a new class that inherits from <see cref="BasePTModuleSettings"/>, 17 /// you MUST register it in <see cref="SettingsSerializationContext"/> by adding a 18 /// <c>[JsonSerializable(typeof(YourNewSettingsClass))]</c> attribute.</para> 19 /// <para>Failure to register the type will cause <see cref="ToJsonString"/> to throw 20 /// <see cref="InvalidOperationException"/> at runtime.</para> 21 /// <para>See <see cref="SettingsSerializationContext"/> for registration instructions.</para> 22 /// </remarks> 23 public abstract class BasePTModuleSettings 24 { 25 // Cached JsonSerializerOptions for Native AOT compatibility 26 private static readonly JsonSerializerOptions _jsonSerializerOptions = new JsonSerializerOptions 27 { 28 TypeInfoResolver = SettingsSerializationContext.Default, 29 }; 30 31 // Gets or sets name of the powertoy module. 32 [JsonPropertyName("name")] 33 public string Name { get; set; } 34 35 // Gets or sets the powertoys version. 36 [JsonPropertyName("version")] 37 public string Version { get; set; } 38 39 /// <summary> 40 /// Converts the current settings object to a JSON string. 41 /// </summary> 42 /// <returns>JSON string representation of this settings object.</returns> 43 /// <exception cref="InvalidOperationException"> 44 /// Thrown when the runtime type is not registered in <see cref="SettingsSerializationContext"/>. 45 /// All derived types must be registered with <c>[JsonSerializable(typeof(YourType))]</c> attribute. 46 /// </exception> 47 /// <remarks> 48 /// This method uses Native AOT-compatible JSON serialization. The runtime type must be 49 /// registered in <see cref="SettingsSerializationContext"/> for serialization to work. 50 /// </remarks> 51 public virtual string ToJsonString() 52 { 53 // By default JsonSerializer will only serialize the properties in the base class. This can be avoided by passing the object type (more details at https://stackoverflow.com/a/62498888) 54 var runtimeType = GetType(); 55 56 // For Native AOT compatibility, get JsonTypeInfo from the TypeInfoResolver 57 var typeInfo = _jsonSerializerOptions.TypeInfoResolver?.GetTypeInfo(runtimeType, _jsonSerializerOptions); 58 59 if (typeInfo == null) 60 { 61 throw new InvalidOperationException($"Type {runtimeType.FullName} is not registered in SettingsSerializationContext. Please add it to the [JsonSerializable] attributes."); 62 } 63 64 // Use AOT-friendly serialization 65 return JsonSerializer.Serialize(this, typeInfo); 66 } 67 68 public override int GetHashCode() 69 { 70 return ToJsonString().GetHashCode(); 71 } 72 73 public override bool Equals(object obj) 74 { 75 var settings = obj as BasePTModuleSettings; 76 return settings?.ToJsonString() == ToJsonString(); 77 } 78 } 79 }