-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathProgram.cs
More file actions
130 lines (107 loc) · 4.34 KB
/
Copy pathProgram.cs
File metadata and controls
130 lines (107 loc) · 4.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
using BFGDL.NET.Configuration;
using BFGDL.NET.Models;
using BFGDL.NET.Services;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace BFGDL.NET;
internal static class Program
{
private static async Task<int> Main(string[] args)
{
return await MainAsync(args);
}
private static async Task<int> MainAsync(string[] args)
{
try
{
var options = CommandLineOptions.Parse(args);
if (options.ShowHelp)
{
CommandLineOptions.PrintHelp();
return 0;
}
if (options.ShowVersion)
{
CommandLineOptions.PrintVersion();
return 0;
}
// Setup dependency injection
var services = new ServiceCollection();
await ConfigureServices(services, options);
var serviceProvider = services.BuildServiceProvider();
var app = serviceProvider.GetRequiredService<Application>();
await app.RunAsync(options);
return 0;
}
catch (Exception ex)
{
// ReSharper disable once MethodHasAsyncOverload
Console.Error.WriteLine($"Error: {ex.Message}");
if (ex.InnerException != null) Console.Error.WriteLine($"Inner Exception: {ex.InnerException.Message}");
Console.Error.WriteLine($"Stack Trace: {ex.StackTrace}");
return 1;
}
}
private static async Task ConfigureServices(IServiceCollection services, CommandLineOptions options)
{
// Load configuration
var configLoader = new ConfigurationLoader();
var appConfig = await configLoader.LoadConfigurationAsync(options.ConfigFilePath);
var config = new ConfigurationBuilder()
.SetBasePath(AppContext.BaseDirectory)
.AddJsonFile("appsettings.json", true, false)
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT")}.json",
true, false)
.AddEnvironmentVariables("BFGDL__")
.Build();
services.AddSingleton<IConfiguration>(config);
// Override config with command-line options if provided
if (options.Platform.HasValue || options.Language.HasValue)
appConfig = appConfig with
{
Platform = options.Platform.GetValueOrDefault(appConfig.Platform),
Language = options.Language.GetValueOrDefault(appConfig.Language)
};
services.AddSingleton(appConfig);
services.AddSingleton(new DownloadOptions
{
Download = options.Download,
MaxConcurrentDownloads = options.MaxConcurrentDownloads,
FetchFromInstallers = options.FetchFromInstallers
});
// Logging
services.AddLogging(builder =>
{
builder.ClearProviders();
builder.AddConsole();
// Apply appsettings.json -> Logging:* rules first
builder.AddConfiguration(config.GetSection("Logging"));
// Still keep the app's config.ini switch, but allow config overrides to win.
if (appConfig.EnableDebugLogging)
builder.SetMinimumLevel(LogLevel.Debug);
});
// HTTP
services.AddHttpClient<IBigFishGamesClient, BigFishGamesClient>()
.ConfigureHttpClient(client =>
{
client.DefaultRequestHeaders.UserAgent.ParseAdd("BFGDL.NET/1.0");
client.Timeout = TimeSpan.FromMinutes(30);
});
services.AddHttpClient<IDownloadService, DownloadService>()
.ConfigureHttpClient(client => { client.Timeout = TimeSpan.FromHours(2); });
services.AddHttpClient<DiskImageStore>();
// HTTP
services.AddHttpClient();
// Paths
services.AddSingleton<IAppPaths, DefaultAppPaths>();
// Services
services.AddSingleton<IDiskImageStore, DiskImageStore>();
services.AddTransient<CatalogFetchService>();
services.AddTransient<InstallerWrapIdFetcher>();
services.AddTransient<BigFishCatalogClient>();
services.AddSingleton<CatalogCache>();
services.AddTransient<InstallerListExporter>();
services.AddTransient<Application>();
}
}