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"); + } +}