From cf28a1bff3e6c479d9cca2232961ec40439dc2d1 Mon Sep 17 00:00:00 2001 From: JusterZhu Date: Sun, 24 May 2026 07:56:15 +0800 Subject: [PATCH] feat(config): add UpdateOptions convenience class, extension points, constructor defaults MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add UpdateOptions static class wrapping all UpdateOption constants - Add new options: UpdateUrl, AppSecretKey, MaxConcurrency, RetryCount, etc. - Add constructor defaults (PopulateDefaults) for best-practice values - Add extension point infrastructure (.Strategy, ResolveExtension) - Fully backward-compatible — existing UpdateOption API unchanged Closes #314 --- .../Configuration/AbstractBootstrap.cs | 50 +++++++++++++------ .../Configuration/UpdateOptions.cs | 49 ++++++++++++++++++ 2 files changed, 84 insertions(+), 15 deletions(-) create mode 100644 src/c#/GeneralUpdate.Core/Configuration/UpdateOptions.cs diff --git a/src/c#/GeneralUpdate.Core/Configuration/AbstractBootstrap.cs b/src/c#/GeneralUpdate.Core/Configuration/AbstractBootstrap.cs index 53b49b61..4e64cedc 100644 --- a/src/c#/GeneralUpdate.Core/Configuration/AbstractBootstrap.cs +++ b/src/c#/GeneralUpdate.Core/Configuration/AbstractBootstrap.cs @@ -1,4 +1,6 @@ +using System; using System.Collections.Concurrent; +using System.Collections.Generic; using System.Diagnostics; using System.Threading.Tasks; using GeneralUpdate.Core.Strategy; @@ -13,38 +15,42 @@ public abstract class AbstractBootstrap { private readonly ConcurrentDictionary _options; - protected internal AbstractBootstrap() => + /// User-registered extension types for lazy instantiation. + private readonly Dictionary _extensions = new(); + + protected internal AbstractBootstrap() + { _options = new ConcurrentDictionary(); + PopulateDefaults(); + } /// - /// Launch async udpate. + /// Populate all UpdateOptions with their best-practice defaults. + /// Subclasses can override to customize. /// - /// - public abstract Task LaunchAsync(); + protected virtual void PopulateDefaults() + { + Option(UpdateOptions.MaxConcurrency, 3); + Option(UpdateOptions.RetryCount, 3); + Option(UpdateOptions.EnableResume, true); + Option(UpdateOptions.VerifyChecksum, true); + Option(UpdateOptions.SilentAutoInstall, false); + } + public abstract Task LaunchAsync(); protected abstract void ExecuteStrategy(); - protected abstract Task ExecuteStrategyAsync(); - protected abstract TBootstrap StrategyFactory(); /// /// Setting update configuration. /// - /// - /// Configuration Action Enumeration. - /// Value - /// public TBootstrap Option(UpdateOption option, T value) { if (value == null) - { _options.TryRemove(option, out _); - } else - { _options[option] = new UpdateOptionValue(option, value); - } return (TBootstrap)this; } @@ -62,5 +68,19 @@ public TBootstrap Option(UpdateOption option, T value) return default; } } + + // ═══════════ Extension point registration ═══════════ + + /// Register a custom update strategy. + public TBootstrap Strategy() where T : IStrategy, new() + { _extensions[typeof(IStrategy)] = typeof(T); return (TBootstrap)this; } + + /// Resolve a registered extension type, or null if not registered. + protected TExtension? ResolveExtension() where TExtension : class + { + if (_extensions.TryGetValue(typeof(TExtension), out var t)) + return Activator.CreateInstance(t) as TExtension; + return null; + } } -} \ No newline at end of file +} diff --git a/src/c#/GeneralUpdate.Core/Configuration/UpdateOptions.cs b/src/c#/GeneralUpdate.Core/Configuration/UpdateOptions.cs new file mode 100644 index 00000000..77b05d32 --- /dev/null +++ b/src/c#/GeneralUpdate.Core/Configuration/UpdateOptions.cs @@ -0,0 +1,49 @@ +using System; +using System.Diagnostics; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Text; + +namespace GeneralUpdate.Core.Configuration +{ + /// + /// Convenience accessor for UpdateOption constants. + /// Maps to the underlying UpdateOption singleton constants. + /// New code should use UpdateOptions.X instead of UpdateOption.X. + /// + public static class UpdateOptions + { + // ═══ Core ═══ + public static UpdateOption AppType => UpdateOption.ValueOf("APPTYPE"); + + // ═══ Existing options (backward-compatible) ═══ + public static UpdateOption Encoding => UpdateOption.Encoding; + public static UpdateOption Format => UpdateOption.Format; + public static UpdateOption DownloadTimeout => UpdateOption.DownloadTimeOut; + public static UpdateOption DriveEnabled => UpdateOption.Drive; + public static UpdateOption PatchEnabled => UpdateOption.Patch; + public static UpdateOption BackupEnabled => UpdateOption.BackUp; + public static UpdateOption Mode => UpdateOption.Mode; + public static UpdateOption Silent => UpdateOption.EnableSilentUpdate; + + // ═══ New options ═══ + public static readonly UpdateOption UpdateUrl = UpdateOption.ValueOf("UPDATEURL"); + public static readonly UpdateOption AppSecretKey = UpdateOption.ValueOf("APPSECRETKEY"); + public static readonly UpdateOption AppName = UpdateOption.ValueOf("APPNAME"); + public static readonly UpdateOption MainAppName = UpdateOption.ValueOf("MAINAPPNAME"); + public static readonly UpdateOption InstallPath = UpdateOption.ValueOf("INSTALLPATH"); + public static readonly UpdateOption ClientVersion = UpdateOption.ValueOf("CLIENTVERSION"); + public static readonly UpdateOption UpgradeClientVersion = UpdateOption.ValueOf("UPGRADECLIENTVERSION"); + public static readonly UpdateOption Platform = UpdateOption.ValueOf("PLATFORM"); + public static readonly UpdateOption SilentAutoInstall = UpdateOption.ValueOf("SILENTAUTOINSTALL"); + public static readonly UpdateOption MaxConcurrency = UpdateOption.ValueOf("MAXCONCURRENCY"); + public static readonly UpdateOption EnableResume = UpdateOption.ValueOf("ENABLERESUME"); + public static readonly UpdateOption RetryCount = UpdateOption.ValueOf("RETRYCOUNT"); + public static readonly UpdateOption VerifyChecksum = UpdateOption.ValueOf("VERIFYCHECKSUM"); + public static readonly UpdateOption ReportUrl = UpdateOption.ValueOf("REPORTURL"); + public static readonly UpdateOption ProductId = UpdateOption.ValueOf("PRODUCTID"); + public static readonly UpdateOption PermissionScript = UpdateOption.ValueOf("PERMISSIONSCRIPT"); + public static readonly UpdateOption Scheme = UpdateOption.ValueOf("SCHEME"); + public static readonly UpdateOption Token = UpdateOption.ValueOf("TOKEN"); + } +}