- App.xaml.cs: register ISearchService, SearchCsvExportService, SearchHtmlExportService, SearchViewModel, SearchView, IDuplicatesService, DuplicatesHtmlExportService, DuplicatesViewModel, DuplicatesView - MainWindow.xaml: add x:Name to SearchTabItem and DuplicatesTabItem (remove FeatureTabBase stubs) - MainWindow.xaml.cs: wire SearchTabItem.Content and DuplicatesTabItem.Content via DI
125 lines
5.0 KiB
C#
125 lines
5.0 KiB
C#
using System.IO;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Hosting;
|
|
using Microsoft.Extensions.Logging;
|
|
using Serilog;
|
|
using SharepointToolbox.Core.Models;
|
|
using SharepointToolbox.Infrastructure.Auth;
|
|
using SharepointToolbox.Infrastructure.Logging;
|
|
using SharepointToolbox.Infrastructure.Persistence;
|
|
using SharepointToolbox.Services;
|
|
using SharepointToolbox.Services.Export;
|
|
using SharepointToolbox.ViewModels;
|
|
using SharepointToolbox.ViewModels.Tabs;
|
|
using SharepointToolbox.Views.Dialogs;
|
|
using SharepointToolbox.Views.Tabs;
|
|
using System.Windows;
|
|
|
|
namespace SharepointToolbox;
|
|
|
|
public partial class App : Application
|
|
{
|
|
[STAThread]
|
|
public static void Main(string[] args)
|
|
{
|
|
using IHost host = Host.CreateDefaultBuilder(args)
|
|
.UseSerilog((ctx, cfg) => cfg
|
|
.WriteTo.File(
|
|
Path.Combine(
|
|
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
|
|
"SharepointToolbox", "logs", "app-.log"),
|
|
rollingInterval: RollingInterval.Day,
|
|
retainedFileCountLimit: 30))
|
|
.ConfigureServices(RegisterServices)
|
|
.Build();
|
|
|
|
host.Start();
|
|
App app = new();
|
|
app.InitializeComponent();
|
|
|
|
var mainWindow = host.Services.GetRequiredService<MainWindow>();
|
|
|
|
// Wire LogPanelSink now that we have the RichTextBox
|
|
Log.Logger = new LoggerConfiguration()
|
|
.WriteTo.File(
|
|
Path.Combine(
|
|
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
|
|
"SharepointToolbox", "logs", "app-.log"),
|
|
rollingInterval: RollingInterval.Day,
|
|
retainedFileCountLimit: 30)
|
|
.WriteTo.Sink(new LogPanelSink(mainWindow.GetLogPanel()))
|
|
.CreateLogger();
|
|
|
|
// Global exception handlers
|
|
app.DispatcherUnhandledException += (s, e) =>
|
|
{
|
|
Log.Fatal(e.Exception, "Unhandled UI exception");
|
|
MessageBox.Show(
|
|
$"A fatal error occurred:\n{e.Exception.Message}\n\nCheck log for details.",
|
|
"Fatal Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
e.Handled = true;
|
|
};
|
|
TaskScheduler.UnobservedTaskException += (s, e) =>
|
|
{
|
|
Log.Fatal(e.Exception, "Unobserved task exception");
|
|
e.SetObserved();
|
|
};
|
|
|
|
app.MainWindow = mainWindow;
|
|
app.MainWindow.Visibility = Visibility.Visible;
|
|
app.Run();
|
|
}
|
|
|
|
private static void RegisterServices(HostBuilderContext ctx, IServiceCollection services)
|
|
{
|
|
var appData = Path.Combine(
|
|
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
|
|
"SharepointToolbox");
|
|
services.AddSingleton(_ => new ProfileRepository(Path.Combine(appData, "profiles.json")));
|
|
services.AddSingleton(_ => new SettingsRepository(Path.Combine(appData, "settings.json")));
|
|
services.AddSingleton<MsalClientFactory>();
|
|
services.AddSingleton<SessionManager>();
|
|
services.AddSingleton<ISessionManager>(sp => sp.GetRequiredService<SessionManager>());
|
|
services.AddSingleton<ProfileService>();
|
|
services.AddSingleton<SettingsService>();
|
|
services.AddSingleton<MainWindowViewModel>();
|
|
services.AddTransient<ProfileManagementViewModel>();
|
|
services.AddTransient<SettingsViewModel>();
|
|
services.AddTransient<ProfileManagementDialog>();
|
|
services.AddTransient<SettingsView>();
|
|
|
|
// Phase 3: Storage
|
|
services.AddTransient<IStorageService, StorageService>();
|
|
services.AddTransient<StorageCsvExportService>();
|
|
services.AddTransient<StorageHtmlExportService>();
|
|
services.AddTransient<StorageViewModel>();
|
|
services.AddTransient<StorageView>();
|
|
|
|
// Phase 3: File Search
|
|
services.AddTransient<ISearchService, SearchService>();
|
|
services.AddTransient<SearchCsvExportService>();
|
|
services.AddTransient<SearchHtmlExportService>();
|
|
services.AddTransient<SearchViewModel>();
|
|
services.AddTransient<SearchView>();
|
|
|
|
// Phase 3: Duplicates
|
|
services.AddTransient<IDuplicatesService, DuplicatesService>();
|
|
services.AddTransient<DuplicatesHtmlExportService>();
|
|
services.AddTransient<DuplicatesViewModel>();
|
|
services.AddTransient<DuplicatesView>();
|
|
|
|
// Phase 2: Permissions
|
|
services.AddTransient<IPermissionsService, PermissionsService>();
|
|
services.AddTransient<ISiteListService, SiteListService>();
|
|
services.AddTransient<CsvExportService>();
|
|
services.AddTransient<HtmlExportService>();
|
|
services.AddTransient<PermissionsViewModel>();
|
|
services.AddTransient<PermissionsView>();
|
|
services.AddTransient<SitePickerDialog>();
|
|
services.AddTransient<Func<TenantProfile, SitePickerDialog>>(sp =>
|
|
profile => new SitePickerDialog(sp.GetRequiredService<ISiteListService>(), profile));
|
|
|
|
services.AddSingleton<MainWindow>();
|
|
}
|
|
}
|