Skip to content

Commit 506601a

Browse files
CopilotJusterZhu
andcommitted
Add ServerUrl to ExtensionHostConfig and update service to use it for downloads
Co-authored-by: JusterZhu <11714536+JusterZhu@users.noreply.github.com>
1 parent 8b7334d commit 506601a

6 files changed

Lines changed: 70 additions & 34 deletions

File tree

src/c#/ExtensionTest/Services/ExtensionServiceTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ private List<AvailableExtension> CreateTestExtensions()
8181
private ExtensionService CreateExtensionService(List<AvailableExtension> extensions)
8282
{
8383
var updateQueue = new GeneralUpdate.Extension.Download.UpdateQueue();
84-
return new ExtensionService(extensions, "/tmp/test-downloads", updateQueue);
84+
return new ExtensionService(extensions, "/tmp/test-downloads", updateQueue, "https://test-server.com/api/extensions");
8585
}
8686

8787
[Fact]

src/c#/GeneralUpdate.Extension/Examples/ExtensionSystemExample.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public void Initialize()
2121
var hostVersion = new Version(1, 5, 0);
2222
var installPath = @"C:\MyApp\Extensions";
2323
var downloadPath = @"C:\MyApp\Temp\Downloads";
24+
var serverUrl = "https://your-server.com/api/extensions";
2425

2526
// Detect current platform
2627
var currentPlatform = DetectCurrentPlatform();
@@ -31,6 +32,7 @@ public void Initialize()
3132
HostVersion = hostVersion,
3233
InstallBasePath = installPath,
3334
DownloadPath = downloadPath,
35+
ServerUrl = serverUrl,
3436
TargetPlatform = currentPlatform,
3537
DownloadTimeout = 300 // 5 minutes
3638
};

src/c#/GeneralUpdate.Extension/ExtensionHostConfig.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ public class ExtensionHostConfig
2626
/// </summary>
2727
public string DownloadPath { get; set; } = null!;
2828

29+
/// <summary>
30+
/// Gets or sets the server URL for extension queries and downloads.
31+
/// This is the base URL used to construct Query and Download endpoints.
32+
/// Example: "https://your-server.com/api/extensions"
33+
/// </summary>
34+
public string ServerUrl { get; set; } = null!;
35+
2936
/// <summary>
3037
/// Gets or sets the target platform (Windows/Linux/macOS).
3138
/// Defaults to Windows if not specified.
@@ -62,6 +69,8 @@ public void Validate()
6269
throw new ArgumentNullException(nameof(InstallBasePath));
6370
if (string.IsNullOrWhiteSpace(DownloadPath))
6471
throw new ArgumentNullException(nameof(DownloadPath));
72+
if (string.IsNullOrWhiteSpace(ServerUrl))
73+
throw new ArgumentNullException(nameof(ServerUrl));
6574
}
6675
}
6776
}

src/c#/GeneralUpdate.Extension/GeneralExtensionHost.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ public GeneralExtensionHost(ExtensionHostConfig config)
109109
new List<Metadata.AvailableExtension>(),
110110
config.DownloadPath,
111111
_updateQueue,
112+
config.ServerUrl,
112113
config.HostVersion,
113114
_validator,
114115
config.DownloadTimeout,
@@ -130,6 +131,7 @@ public GeneralExtensionHost(ExtensionHostConfig config)
130131
/// <param name="hostVersion">The current host application version.</param>
131132
/// <param name="installBasePath">Base directory for extension installations.</param>
132133
/// <param name="downloadPath">Directory for downloading extension packages.</param>
134+
/// <param name="serverUrl">Server base URL for extension queries and downloads.</param>
133135
/// <param name="targetPlatform">The current platform (Windows/Linux/macOS).</param>
134136
/// <param name="downloadTimeout">Download timeout in seconds (default: 300).</param>
135137
/// <param name="authScheme">Optional HTTP authentication scheme (e.g., "Bearer", "Basic").</param>
@@ -140,6 +142,7 @@ public GeneralExtensionHost(
140142
Version hostVersion,
141143
string installBasePath,
142144
string downloadPath,
145+
string serverUrl,
143146
Metadata.TargetPlatform targetPlatform = Metadata.TargetPlatform.Windows,
144147
int downloadTimeout = 300,
145148
string? authScheme = null,
@@ -149,6 +152,7 @@ public GeneralExtensionHost(
149152
HostVersion = hostVersion,
150153
InstallBasePath = installBasePath,
151154
DownloadPath = downloadPath,
155+
ServerUrl = serverUrl,
152156
TargetPlatform = targetPlatform,
153157
DownloadTimeout = downloadTimeout,
154158
AuthScheme = authScheme,

src/c#/GeneralUpdate.Extension/README.md

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,17 @@ Note: This library is currently distributed as source. A NuGet package may be av
3434
using GeneralUpdate.Extension;
3535
using GeneralUpdate.Extension.Metadata;
3636

37-
// Create extension host
38-
var host = new ExtensionHost(
39-
hostVersion: new Version(1, 0, 0),
40-
installPath: @"C:\MyApp\Extensions",
41-
downloadPath: @"C:\MyApp\Downloads",
42-
targetPlatform: TargetPlatform.Windows);
37+
// Create extension host with configuration
38+
var config = new ExtensionHostConfig
39+
{
40+
HostVersion = new Version(1, 0, 0),
41+
InstallBasePath = @"C:\MyApp\Extensions",
42+
DownloadPath = @"C:\MyApp\Downloads",
43+
ServerUrl = "https://your-server.com/api/extensions",
44+
TargetPlatform = TargetPlatform.Windows
45+
};
46+
47+
var host = new GeneralExtensionHost(config);
4348

4449
// Load installed extensions
4550
host.LoadInstalledExtensions();
@@ -70,25 +75,29 @@ public class YourModule : IModule
7075
{
7176
public void RegisterTypes(IContainerRegistry containerRegistry)
7277
{
73-
var hostVersion = new Version(1, 0, 0);
74-
var installPath = @"C:\MyApp\Extensions";
75-
var downloadPath = @"C:\MyApp\Downloads";
76-
var platform = Metadata.TargetPlatform.Windows;
78+
var config = new ExtensionHostConfig
79+
{
80+
HostVersion = new Version(1, 0, 0),
81+
InstallBasePath = @"C:\MyApp\Extensions",
82+
DownloadPath = @"C:\MyApp\Downloads",
83+
ServerUrl = "https://your-server.com/api/extensions",
84+
TargetPlatform = Metadata.TargetPlatform.Windows
85+
};
7786

7887
// Register as singletons
7988
containerRegistry.RegisterSingleton<Core.IExtensionCatalog>(() =>
80-
new Core.ExtensionCatalog(installPath));
89+
new Core.ExtensionCatalog(config.InstallBasePath));
8190

8291
containerRegistry.RegisterSingleton<Compatibility.ICompatibilityValidator>(() =>
83-
new Compatibility.CompatibilityValidator(hostVersion));
92+
new Compatibility.CompatibilityValidator(config.HostVersion));
8493

8594
containerRegistry.RegisterSingleton<Download.IUpdateQueue, Download.UpdateQueue>();
8695

8796
containerRegistry.RegisterSingleton<PackageGeneration.IExtensionPackageGenerator,
8897
PackageGeneration.ExtensionPackageGenerator>();
8998

9099
containerRegistry.RegisterSingleton<IExtensionHost>(() =>
91-
new ExtensionHost(hostVersion, installPath, downloadPath, platform));
100+
new GeneralExtensionHost(config));
92101
}
93102
}
94103

@@ -102,24 +111,28 @@ var host = container.Resolve<IExtensionHost>();
102111
using Microsoft.Extensions.DependencyInjection;
103112

104113
var services = new ServiceCollection();
105-
var hostVersion = new Version(1, 0, 0);
106-
var installPath = @"C:\Extensions";
107-
var downloadPath = @"C:\Downloads";
114+
var config = new ExtensionHostConfig
115+
{
116+
HostVersion = new Version(1, 0, 0),
117+
InstallBasePath = @"C:\Extensions",
118+
DownloadPath = @"C:\Downloads",
119+
ServerUrl = "https://your-server.com/api/extensions",
120+
TargetPlatform = Metadata.TargetPlatform.Windows
121+
};
108122

109123
services.AddSingleton<Core.IExtensionCatalog>(sp =>
110-
new Core.ExtensionCatalog(installPath));
124+
new Core.ExtensionCatalog(config.InstallBasePath));
111125

112126
services.AddSingleton<Compatibility.ICompatibilityValidator>(sp =>
113-
new Compatibility.CompatibilityValidator(hostVersion));
127+
new Compatibility.CompatibilityValidator(config.HostVersion));
114128

115129
services.AddSingleton<Download.IUpdateQueue, Download.UpdateQueue>();
116130

117131
services.AddSingleton<PackageGeneration.IExtensionPackageGenerator,
118132
PackageGeneration.ExtensionPackageGenerator>();
119133

120134
services.AddSingleton<IExtensionHost>(sp =>
121-
new ExtensionHost(hostVersion, installPath, downloadPath,
122-
Metadata.TargetPlatform.Windows));
135+
new GeneralExtensionHost(config));
123136

124137
var provider = services.BuildServiceProvider();
125138
var host = provider.GetRequiredService<IExtensionHost>();
@@ -128,11 +141,16 @@ var host = provider.GetRequiredService<IExtensionHost>();
128141
#### Without DI (Direct Instantiation)
129142

130143
```csharp
131-
var host = new ExtensionHost(
132-
new Version(1, 0, 0),
133-
@"C:\Extensions",
134-
@"C:\Downloads",
135-
Metadata.TargetPlatform.Windows);
144+
var config = new ExtensionHostConfig
145+
{
146+
HostVersion = new Version(1, 0, 0),
147+
InstallBasePath = @"C:\Extensions",
148+
DownloadPath = @"C:\Downloads",
149+
ServerUrl = "https://your-server.com/api/extensions",
150+
TargetPlatform = Metadata.TargetPlatform.Windows
151+
};
152+
153+
var host = new GeneralExtensionHost(config);
136154
```
137155

138156
### 2. Loading and Managing Extensions

src/c#/GeneralUpdate.Extension/Services/ExtensionService.cs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public class ExtensionService : IExtensionService
2525
private readonly Download.IUpdateQueue _updateQueue;
2626
private readonly string? _authScheme;
2727
private readonly string? _authToken;
28+
private readonly string _serverUrl;
2829

2930
/// <summary>
3031
/// Occurs when download progress updates during package retrieval.
@@ -47,6 +48,7 @@ public class ExtensionService : IExtensionService
4748
/// <param name="availableExtensions">List of available extensions</param>
4849
/// <param name="downloadPath">Directory path where extension packages will be downloaded</param>
4950
/// <param name="updateQueue">The update queue for managing operation state</param>
51+
/// <param name="serverUrl">Server base URL for extension queries and downloads</param>
5052
/// <param name="hostVersion">Optional host version for compatibility checking</param>
5153
/// <param name="validator">Optional compatibility validator</param>
5254
/// <param name="downloadTimeout">Timeout in seconds for download operations (default: 300)</param>
@@ -56,6 +58,7 @@ public ExtensionService(
5658
List<AvailableExtension> availableExtensions,
5759
string downloadPath,
5860
Download.IUpdateQueue updateQueue,
61+
string serverUrl,
5962
Version? hostVersion = null,
6063
Compatibility.ICompatibilityValidator? validator = null,
6164
int downloadTimeout = 300,
@@ -67,7 +70,11 @@ public ExtensionService(
6770
if (string.IsNullOrWhiteSpace(downloadPath))
6871
throw new ArgumentNullException(nameof(downloadPath));
6972

73+
if (string.IsNullOrWhiteSpace(serverUrl))
74+
throw new ArgumentNullException(nameof(serverUrl));
75+
7076
_downloadPath = downloadPath;
77+
_serverUrl = serverUrl.TrimEnd('/'); // Remove trailing slash for consistent URL construction
7178
_updateQueue = updateQueue ?? throw new ArgumentNullException(nameof(updateQueue));
7279
_downloadTimeout = downloadTimeout;
7380
_hostVersion = hostVersion;
@@ -302,18 +309,14 @@ public async Task<HttpResponseDTO<DownloadExtensionDTO>> Download(string id)
302309

303310
var descriptor = operation.Extension.Descriptor;
304311

305-
if (string.IsNullOrWhiteSpace(descriptor.DownloadUrl))
306-
{
307-
_updateQueue.ChangeState(operation.OperationId, GeneralUpdate.Extension.Download.UpdateState.UpdateFailed, "Download URL is missing");
308-
OnDownloadFailed(descriptor.Name, descriptor.DisplayName);
309-
return null;
310-
}
312+
// Construct download URL from server URL and extension ID
313+
var downloadUrl = $"{_serverUrl}/Download/{descriptor.Name}";
311314

312315
try
313316
{
314317
_updateQueue.ChangeState(operation.OperationId, GeneralUpdate.Extension.Download.UpdateState.Updating);
315318

316-
// Determine file format from URL or default to .zip
319+
// Determine file format from descriptor or default to .zip
317320
var format = !string.IsNullOrWhiteSpace(descriptor.DownloadUrl) && descriptor.DownloadUrl!.Contains(".")
318321
? Path.GetExtension(descriptor.DownloadUrl)
319322
: ".zip";
@@ -322,7 +325,7 @@ public async Task<HttpResponseDTO<DownloadExtensionDTO>> Download(string id)
322325
var versionInfo = new VersionInfo
323326
{
324327
Name = $"{descriptor.Name}_{descriptor.Version}",
325-
Url = descriptor.DownloadUrl,
328+
Url = downloadUrl,
326329
Hash = descriptor.PackageHash,
327330
Version = descriptor.Version,
328331
Size = descriptor.PackageSize,

0 commit comments

Comments
 (0)