feat: 重构 TodoList 架构,新增动态 API 与 MAUI 内嵌 Web 服务
This commit is contained in:
@@ -1,4 +1,10 @@
|
||||
using System.Text.Json;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using TodoList.Application;
|
||||
using TodoList.Application.Data;
|
||||
using TodoList.Maui.Models;
|
||||
using TodoList.Maui.Services;
|
||||
using TodoList.Maui.Services.Platforms;
|
||||
|
||||
@@ -17,21 +23,88 @@ public static class MauiProgram
|
||||
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
|
||||
});
|
||||
|
||||
builder.Services.AddSingleton<IHotKeySettingsService, HotKeySettingsService>();
|
||||
builder.Services.AddSingleton<IGlobalHotKeyService>(sp => new NullGlobalHotKeyService());
|
||||
var appSettings = LoadAppSettings();
|
||||
|
||||
// Set default connection string if not provided
|
||||
if (string.IsNullOrEmpty(appSettings.WebServer.ConnectionString))
|
||||
{
|
||||
var dbPath = Path.Combine(FileSystem.AppDataDirectory, "todolist.db");
|
||||
appSettings.WebServer.ConnectionString = $"Data Source={dbPath}";
|
||||
}
|
||||
|
||||
builder.Services.AddSingleton(appSettings);
|
||||
var connectionString = appSettings.WebServer.ConnectionString;
|
||||
|
||||
builder.Services.AddApplicationServices(connectionString);
|
||||
|
||||
builder.Services.AddSingleton<IHotKeySettingsService>(sp =>
|
||||
new HotKeySettingsService(sp.GetRequiredService<AppSettings>()));
|
||||
builder.Services.AddSingleton<IGlobalHotKeyService>(sp => GlobalHotKeyServiceFactory.Create());
|
||||
builder.Services.AddSingleton<ISystemTrayService>(sp =>
|
||||
{
|
||||
#if WINDOWS
|
||||
return new NullSystemTrayService();
|
||||
return new WindowsSystemTrayService();
|
||||
#else
|
||||
return new NullSystemTrayService();
|
||||
#endif
|
||||
});
|
||||
builder.Services.AddSingleton<IEmbeddedWebServerService, EmbeddedWebServerService>();
|
||||
|
||||
#if DEBUG
|
||||
builder.Logging.AddDebug();
|
||||
builder.Logging.AddDebug();
|
||||
#endif
|
||||
|
||||
return builder.Build();
|
||||
var app = builder.Build();
|
||||
|
||||
// Ensure database directory exists and apply migrations
|
||||
using (var scope = app.Services.CreateScope())
|
||||
{
|
||||
try
|
||||
{
|
||||
var dbContext = scope.ServiceProvider.GetRequiredService<TodoDbContext>();
|
||||
|
||||
// Ensure database directory exists for the actual connection string
|
||||
var sqliteBuilder = new SqliteConnectionStringBuilder(connectionString);
|
||||
var actualDbPath = sqliteBuilder.DataSource;
|
||||
if (!string.IsNullOrEmpty(actualDbPath))
|
||||
{
|
||||
// If it's a relative path, we might need to resolve it,
|
||||
// but for SQLite, it's usually better to have absolute paths.
|
||||
// For MAUI, FileSystem.AppDataDirectory returns an absolute path.
|
||||
var dbDir = Path.GetDirectoryName(actualDbPath);
|
||||
if (!string.IsNullOrEmpty(dbDir) && !Directory.Exists(dbDir))
|
||||
{
|
||||
Directory.CreateDirectory(dbDir);
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure database is up to date
|
||||
dbContext.Database.Migrate();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"Database initialization failed: {ex.Message}");
|
||||
// Fallback to EnsureCreated if Migrate fails (though Migrate is preferred)
|
||||
using var context = scope.ServiceProvider.GetRequiredService<TodoDbContext>();
|
||||
context.Database.EnsureCreated();
|
||||
}
|
||||
}
|
||||
|
||||
var webServer = app.Services.GetRequiredService<IEmbeddedWebServerService>();
|
||||
_ = webServer.StartAsync();
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
private static AppSettings LoadAppSettings()
|
||||
{
|
||||
var settingsPath = Path.Combine(AppContext.BaseDirectory, "appsettings.json");
|
||||
if (!File.Exists(settingsPath))
|
||||
{
|
||||
return new AppSettings();
|
||||
}
|
||||
|
||||
var json = File.ReadAllText(settingsPath);
|
||||
return JsonSerializer.Deserialize<AppSettings>(json) ?? new AppSettings();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user