Refactor ILibraryService and LibraryService to support new metadata handling features, including remote image management and enhanced label summaries. Update LabelSummary to include ImagePath for better visual representation. Revise MetadataMatchViewModel and MetadataScanViewModel to accommodate new image loading logic. Enhance README.md to document these updates and new functionalities.
This commit is contained in:
+82
-81
@@ -1,81 +1,82 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using PLib.Desktop.Imaging;
|
||||
using PLib.Desktop.Services;
|
||||
using PLib.Desktop.Settings;
|
||||
using PLib.Desktop.ViewModels;
|
||||
using PLib.Infrastructure;
|
||||
using PLib.Infrastructure.Storage;
|
||||
using Serilog;
|
||||
|
||||
namespace PLib.Desktop;
|
||||
|
||||
/// <summary>
|
||||
/// Composition root. Everything the application is made of is wired up here and nowhere else.
|
||||
/// </summary>
|
||||
internal static class AppHost
|
||||
{
|
||||
public static IHost Create(string[] args)
|
||||
{
|
||||
// The paths are needed to locate the user settings file, which is itself a
|
||||
// configuration source — so they are built before the container exists and then
|
||||
// handed to it as an instance.
|
||||
var paths = new AppPaths();
|
||||
|
||||
// A desktop app is launched from arbitrary working directories, so the content root
|
||||
// has to be the folder the executable lives in rather than Environment.CurrentDirectory.
|
||||
var builder = Host.CreateApplicationBuilder(new HostApplicationBuilderSettings
|
||||
{
|
||||
Args = args,
|
||||
ContentRootPath = AppContext.BaseDirectory,
|
||||
});
|
||||
|
||||
builder.Configuration.AddJsonFile(
|
||||
Path.Combine(paths.DataDirectory, "settings.json"),
|
||||
optional: true,
|
||||
reloadOnChange: true);
|
||||
|
||||
ConfigureLogging(builder, paths);
|
||||
|
||||
builder.Services.AddSingleton<IAppPaths>(paths);
|
||||
|
||||
builder.Services.AddOptions<AppearanceOptions>()
|
||||
.Bind(builder.Configuration.GetSection(AppearanceOptions.SectionName));
|
||||
|
||||
builder.Services.AddOptions<PlaybackOptions>()
|
||||
.Bind(builder.Configuration.GetSection(PlaybackOptions.SectionName))
|
||||
.ValidateDataAnnotations();
|
||||
builder.Services.AddPLibInfrastructure(builder.Configuration);
|
||||
|
||||
builder.Services.AddSingleton<ThumbnailCache>();
|
||||
builder.Services.AddSingleton<IThumbnailLoader>(sp => sp.GetRequiredService<ThumbnailCache>());
|
||||
builder.Services.AddSingleton<IAppSettingsStore, JsonAppSettingsStore>();
|
||||
builder.Services.AddSingleton<IFolderPicker, StorageProviderFolderPicker>();
|
||||
builder.Services.AddSingleton<ISystemShell, SystemShell>();
|
||||
builder.Services.AddSingleton<IThemeService, ThemeService>();
|
||||
builder.Services.AddSingleton<MainWindowViewModel>();
|
||||
|
||||
// Scoped, not singleton: the settings dialog edits a working copy, so each opening
|
||||
// gets its own model and a cancelled edit never leaks into the next one.
|
||||
builder.Services.AddScoped<SettingsViewModel>();
|
||||
|
||||
return builder.Build();
|
||||
}
|
||||
|
||||
private static void ConfigureLogging(HostApplicationBuilder builder, IAppPaths paths)
|
||||
{
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
.MinimumLevel.Information()
|
||||
.WriteTo.Console()
|
||||
.WriteTo.File(
|
||||
Path.Combine(paths.DataDirectory, "logs", "plib-.log"),
|
||||
rollingInterval: RollingInterval.Day,
|
||||
retainedFileCountLimit: 7)
|
||||
.CreateLogger();
|
||||
|
||||
builder.Logging.ClearProviders();
|
||||
builder.Logging.AddSerilog(Log.Logger, dispose: true);
|
||||
}
|
||||
}
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using PLib.Desktop.Imaging;
|
||||
using PLib.Desktop.Services;
|
||||
using PLib.Desktop.Settings;
|
||||
using PLib.Desktop.ViewModels;
|
||||
using PLib.Infrastructure;
|
||||
using PLib.Infrastructure.Storage;
|
||||
using Serilog;
|
||||
|
||||
namespace PLib.Desktop;
|
||||
|
||||
/// <summary>
|
||||
/// Composition root. Everything the application is made of is wired up here and nowhere else.
|
||||
/// </summary>
|
||||
internal static class AppHost
|
||||
{
|
||||
public static IHost Create(string[] args)
|
||||
{
|
||||
// The paths are needed to locate the user settings file, which is itself a
|
||||
// configuration source — so they are built before the container exists and then
|
||||
// handed to it as an instance.
|
||||
var paths = new AppPaths();
|
||||
|
||||
// A desktop app is launched from arbitrary working directories, so the content root
|
||||
// has to be the folder the executable lives in rather than Environment.CurrentDirectory.
|
||||
var builder = Host.CreateApplicationBuilder(new HostApplicationBuilderSettings
|
||||
{
|
||||
Args = args,
|
||||
ContentRootPath = AppContext.BaseDirectory,
|
||||
});
|
||||
|
||||
builder.Configuration.AddJsonFile(
|
||||
Path.Combine(paths.DataDirectory, "settings.json"),
|
||||
optional: true,
|
||||
reloadOnChange: true);
|
||||
|
||||
ConfigureLogging(builder, paths);
|
||||
|
||||
builder.Services.AddSingleton<IAppPaths>(paths);
|
||||
|
||||
builder.Services.AddOptions<AppearanceOptions>()
|
||||
.Bind(builder.Configuration.GetSection(AppearanceOptions.SectionName));
|
||||
|
||||
builder.Services.AddOptions<PlaybackOptions>()
|
||||
.Bind(builder.Configuration.GetSection(PlaybackOptions.SectionName))
|
||||
.ValidateDataAnnotations();
|
||||
builder.Services.AddPLibInfrastructure(builder.Configuration);
|
||||
|
||||
builder.Services.AddSingleton<ThumbnailCache>();
|
||||
builder.Services.AddSingleton<IThumbnailLoader>(sp => sp.GetRequiredService<ThumbnailCache>());
|
||||
builder.Services.AddSingleton<IAppSettingsStore, JsonAppSettingsStore>();
|
||||
builder.Services.AddSingleton<IFolderPicker, StorageProviderFolderPicker>();
|
||||
builder.Services.AddSingleton<ISystemShell, SystemShell>();
|
||||
builder.Services.AddSingleton<IThemeService, ThemeService>();
|
||||
builder.Services.AddSingleton<RemoteImageLoader>();
|
||||
builder.Services.AddSingleton<MainWindowViewModel>();
|
||||
|
||||
// Scoped, not singleton: the settings dialog edits a working copy, so each opening
|
||||
// gets its own model and a cancelled edit never leaks into the next one.
|
||||
builder.Services.AddScoped<SettingsViewModel>();
|
||||
|
||||
return builder.Build();
|
||||
}
|
||||
|
||||
private static void ConfigureLogging(HostApplicationBuilder builder, IAppPaths paths)
|
||||
{
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
.MinimumLevel.Information()
|
||||
.WriteTo.Console()
|
||||
.WriteTo.File(
|
||||
Path.Combine(paths.DataDirectory, "logs", "plib-.log"),
|
||||
rollingInterval: RollingInterval.Day,
|
||||
retainedFileCountLimit: 7)
|
||||
.CreateLogger();
|
||||
|
||||
builder.Logging.ClearProviders();
|
||||
builder.Logging.AddSerilog(Log.Logger, dispose: true);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user