-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathApp.xaml.cs
More file actions
166 lines (140 loc) · 6.42 KB
/
App.xaml.cs
File metadata and controls
166 lines (140 loc) · 6.42 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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
using System;
using System.Threading.Tasks;
using System.Windows;
using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.Messaging;
using Emgu.CV;
using GcLib;
using ImagerViewer.Models;
using ImagerViewer.Utilities.IO;
using ImagerViewer.Utilities.Logging;
using ImagerViewer.Utilities.Services;
using ImagerViewer.Utilities.Themes;
using ImagerViewer.ViewModels;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Serilog;
namespace ImagerViewer;
/// <summary>
/// ImageViewer is a demo app for the <see cref="GcLib"/> library. The app demonstrates how to connect to devices, change device parameter settings and display live image streams. The app also provide some elementary recording and playback functionality.
/// </summary>
public partial class App : Application
{
/// <summary>
/// Enables and disables logging of application events.
/// </summary>
public static bool IsLoggingEnabled { get; set; }
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
// Create storage of logging data.
var logModel = new LogModel();
// Configure logging.
Log.Logger = new LoggerConfiguration()
.Filter.ByExcluding(_ => !IsLoggingEnabled)
.MinimumLevel.Verbose()
.WriteTo.LogModelSink(logModel: logModel, minimumLevel: Serilog.Events.LogEventLevel.Verbose)
.WriteTo.StatusBarSink(messenger: WeakReferenceMessenger.Default, minimumLevel: Serilog.Events.LogEventLevel.Information)
.WriteTo.File(path: @"log.txt",
rollingInterval: RollingInterval.Day,
outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {Message:lj}{NewLine}{Exception}")
#if DEBUG
.WriteTo.Debug(outputTemplate: "[{Timestamp:HH:mm:ss.fff} {Level:u3}] {Message:lj}{NewLine}{Exception}")
#endif
.CreateLogger();
// Enable logging of unhandled exceptions.
SetupUnhandledExceptionLogging();
// Start logging.
IsLoggingEnabled = true;
Log.Information("{App} started (v{version})", MainWindowViewModel.Title, MainWindowViewModel.MajorMinorVersion);
// Configure services for dependency injection.
Ioc.Default.ConfigureServices(
new ServiceCollection()
.AddTransient<IDispatcherService, DispatcherService>()
.AddTransient<IThemeService, ThemeService>()
.AddScoped<IMetroWindowService, MetroWindowService>()
.AddSingleton<IConfigurationService, ConfigurationService>()
.AddSingleton<ISettingsService, ApplicationSettingsService>()
.AddScoped<MainWindowViewModel>()
.AddScoped<ImageProcessingViewModel>()
.AddScoped<ImageDisplayViewModel>()
.AddScoped<DeviceViewModel>()
.AddScoped<PlayBackViewModel>()
.AddScoped<AcquisitionViewModel>()
.AddScoped<HistogramViewModel>()
.AddTransient<OptionsWindowViewModel>()
.AddTransient<LogWindowViewModel>()
.AddTransient<ShortcutWindowViewModel>()
.AddSingleton(logModel)
.AddSingleton(new ImageModel())
.AddSingleton(new DeviceModel())
.AddSingleton<IDeviceProvider, GcSystem>()
.AddLogging(loggingBuilder => loggingBuilder.AddSerilog())
.BuildServiceProvider());
InitializeLibraries();
Log.Debug("Services configured");
// Restore user settings to UI.
Ioc.Default.GetRequiredService<ISettingsService>().RestoreSettings();
Log.Debug("Application settings restored");
// Shut down all child windows on main window closing.
Current.ShutdownMode = ShutdownMode.OnMainWindowClose;
}
/// <summary>
/// Setup logging of unhandled exceptions raised in application.
/// </summary>
private void SetupUnhandledExceptionLogging()
{
// Logs all main UI thread related exceptions.
DispatcherUnhandledException += (s, e) => { LogUnhandledException(e.Exception, "DispatcherUnhandledException", s.ToString()); e.Handled = true; Current.Shutdown(-1); };
// Logs all other exceptions in background threads.
AppDomain.CurrentDomain.UnhandledException += (s, e) => { LogUnhandledException(e.ExceptionObject, "AppDomain.CurrentDomain.UnhandledException", s?.ToString()); Environment.Exit(1); };
// Logs exceptions from uses of a task scheduler for async operations.
TaskScheduler.UnobservedTaskException += (s, e) => { LogUnhandledException(e.Exception, "TaskScheduler.UnobservedTaskException", s.ToString()); e.SetObserved(); };
}
/// <summary>
/// Logs an unhandled exception.
/// </summary>
/// <param name="exceptionObject">Exception object.</param>
/// <param name="type">Exception type.</param>
/// <param name="source">Exception source.</param>
private static void LogUnhandledException(object exceptionObject, string type, string source)
{
// Check if object is null.
if (exceptionObject is not Exception ex)
ex = new NotSupportedException("Unhandled exception: " + exceptionObject.ToString());
Log.Fatal(ex, "Unhandled exception of type {Type} raised by {Source}!", type, source);
}
protected override void OnExit(ExitEventArgs e)
{
// Persist user settings.
Ioc.Default.GetRequiredService<ISettingsService>().StoreSettings();
Log.Debug("Application settings stored");
// Close libraries.
CloseLibraries();
Log.Information("{App} closed", MainWindowViewModel.Title);
Log.CloseAndFlush();
base.OnExit(e);
}
/// <summary>
/// Initializes libraries used in the application.
/// </summary>
private static void InitializeLibraries()
{
// Initialize EmguCV.
if (CvInvoke.Init() == false)
throw new InvalidOperationException("Emgu CV could not be initialized!");
// Initialize GcLib with logger.
GcLibrary.Init(logger: Ioc.Default.GetService<ILogger<App>>());
}
/// <summary>
/// Close libraries used in the application.
/// </summary>
private static void CloseLibraries()
{
// Dispose system level in GcLib.
var system = Ioc.Default.GetRequiredService<IDeviceProvider>() as GcSystem;
system?.Dispose();
// Close GcLib.
GcLibrary.Close();
}
}