GeneralUpdate.Extension — Execution Flow Deep Dive
Target Audience: Developers who need to understand Extension's internal management engine
After reading you will understand:
GeneralExtensionHost's DI injection architecture and legacy compatibility mode- The complete nine-stage execution chain of
UpdateExtensionAsync- DependencyResolver's topological sorting and circular dependency detection
- Version compatibility checking and platform matching decision logic
InstallExtensionAsync's backup → cleanup → extract → atomic write flow- Zip Slip path traversal protection implementation details
- Extension Catalog's atomic write and crash-safe design
- DownloadQueueManager's concurrency control
- IExtensionLifecycleHooks' 8 event injection points
Table of Contents
- Architecture Overview
- Entry: GeneralExtensionHost's Dual Constructor Design
- ExtensionHostBuilder: DI Builder Pattern
- UpdateExtensionAsync: One-Click Update Complete Flow
- Dependency Resolution: DependencyResolver Deep Dive
- Compatibility Checks: Version + Platform Dual Validation
- Download: DownloadQueueManager Concurrency Control
- Install: InstallExtensionAsync Security Guarantees
- Catalog: Atomic Writes & Crash Safety
- Lifecycle Hooks: 8 Event Injection Points
- Key Code Path Index
1. Architecture Overview
1.1 Six-Layer Service Architecture
Extension uses a DI + Builder pattern design where all services are replaceable:
┌──────────────────────────────────────────────────────────────┐
│ GeneralExtensionHost (Orchestration Layer) │
│ │
│ ┌──────────────┐ ┌ ──────────────┐ ┌──────────────────┐ │
│ │ IExtension │ │ IExtension │ │ IVersion │ │
│ │ HttpClient │ │ Catalog │ │ Compatibility │ │
│ │ Server API │ │ Local │ │ Checker │ │
│ │ communication │ │ manifest │ │ Version check │ │
│ └──────────────┘ └──────────────┘ └──────────────────┘ │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ IDownload │ │ IDependency │ │ IPlatformMatcher │ │
│ │ QueueManager │ │ Resolver │ │ Platform match │ │
│ │ Concurrency │ │ Topo sort │ │ │ │
│ └──────────────┘ └──────────────┘ └──────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ IExtensionLifecycleHooks (Optional) │ │
│ │ Before/After Install, Activate, Deactivate, Uninstall │ │
│ └──────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
1.2 Core Design Principles
| Principle | Description |
|---|---|
| Full DI Replaceability | Every service has an interface, injected via constructor, testable |
| Builder Pattern | ExtensionHostBuilder provides fluent config API with ConfigureServices |
| Legacy Compatibility | Parameterless constructor auto-creates defaults, old code unchanged |
| Atomic Writes | Catalog manifest.json writes to .tmp then renames, crash-safe |
| Zip Slip Protection | SafeExtractZipAsync validates each entry's destination path |
| Recursive Dependency Install | Missing dependencies auto-trigger recursive UpdateExtensionAsync |
2. Entry: GeneralExtensionHost's Dual Constructor Design
DI Constructor (Recommended)
public GeneralExtensionHost(
ExtensionHostOptions options,
IExtensionHttpClient httpClient,
IExtensionCatalog catalog,
IVersionCompatibilityChecker compatibilityChecker,
IDownloadQueueManager downloadQueue,
IDependencyResolver dependencyResolver,
IPlatformMatcher platformMatcher,
IExtensionLifecycleHooks? lifecycleHooks = null,
IExtensionMetadataMapper? metadataMapper = null)
Legacy Constructor (Backward Compatible)
public GeneralExtensionHost(ExtensionHostOptions options)
{
// Auto-creates default implementations
_httpClient = new ExtensionHttpClient(options.ServerUrl, ...);
ExtensionCatalog = new ExtensionCatalog(options.CatalogPath ?? options.ExtensionsDirectory);
_compatibilityChecker = new VersionCompatibilityChecker();
_downloadQueue = new DownloadQueueManager();
_dependencyResolver = new DependencyResolver(ExtensionCatalog);
_platformMatcher = new PlatformMatcher();
}
3. ExtensionHostBuilder: DI Builder Pattern
var host = new ExtensionHostBuilder()
.ConfigureOptions(options => {
options.HostVersion = "2.0.0";
options.ExtensionsDirectory = "./extensions";
options.ServerUrl = "https://api.example.com";
})
.ConfigureServices(services => {
services.AddSingleton<IExtensionHttpClient, CustomHttpClient>();
services.AddSingleton<IExtensionLifecycleHooks, MyLifecycleHooks>();
})
.Build();
4. UpdateExtensionAsync: One-Click Update Complete Flow
This is Extension's core method, chaining: query → compatibility → platform → dependency recursion → download → hash verify → safe install → catalog update → event notification.
Nine Stages Summary
| Stage | Operation | Failure Behavior |
|---|---|---|
| ① | Notify Queued | — |
| ② | Query Server | Throw |
| ③ | Version Compatibility | Throw |
| ④ | Platform Match | Throw |
| ⑤ | Dependency Resolution | Recursive install |
| ⑥ | Download | Throw |
| ⑦ | SHA256 Verify | Delete file, throw |
| ⑧ | Safe Install | Rollback on failure |
| ⑨ | Catalog Update | Atomic write |
5. Dependency Resolution: DependencyResolver Deep Dive
Topological Sort
public List<string> GetTransitiveDependencies(List<string> directDependencies)
{
// 1. Build dependency graph (adjacency list)
// 2. Kahn's algorithm for topological sort
// 3. Detect circular dependencies (A → B → A)
// 4. Return install order (dependencies first)
}
Dependency Install Decision Tree
sortedDeps = DependencyResolver.GetTransitiveDependencies(deps)
missingDeps = sortedDeps.Where(d => Catalog.GetInstalledExtensionById(d) == null)
foreach dep in sortedDeps:
if dep is missing:
await UpdateExtensionAsync(dep) // Recursive install