|
1 | | -using Microsoft.Extensions.Logging; |
2 | | -using System; |
3 | | -using System.Collections.Generic; |
4 | | -using System.IO; |
5 | | -using System.Linq; |
6 | | -using System.Runtime.InteropServices.WindowsRuntime; |
7 | | -using Windows.ApplicationModel; |
8 | | -using Windows.ApplicationModel.Activation; |
9 | | -using Windows.Foundation; |
10 | | -using Windows.Foundation.Collections; |
11 | | -using Windows.UI.Xaml; |
12 | | -using Windows.UI.Xaml.Controls; |
13 | | -using Windows.UI.Xaml.Controls.Primitives; |
14 | | -using Windows.UI.Xaml.Data; |
15 | | -using Windows.UI.Xaml.Input; |
16 | | -using Windows.UI.Xaml.Media; |
17 | | -using Windows.UI.Xaml.Navigation; |
18 | | - |
19 | 1 | namespace MADE.Samples |
20 | 2 | { |
21 | | - using MADE.UI.Views.Dialogs; |
| 3 | + using System; |
| 4 | + using System.Threading.Tasks; |
| 5 | + using CommunityToolkit.Mvvm.DependencyInjection; |
| 6 | + using CommunityToolkit.Mvvm.Messaging; |
| 7 | + using MADE.Diagnostics; |
| 8 | + using MADE.Diagnostics.Logging; |
| 9 | + using MADE.Samples.Features.Home.Pages; |
| 10 | + using MADE.Samples.Infrastructure.ViewModels; |
| 11 | + using MADE.UI.Views.Navigation; |
| 12 | + using Microsoft.Extensions.DependencyInjection; |
| 13 | + using Windows.ApplicationModel.Activation; |
| 14 | + using Windows.UI.Xaml; |
| 15 | + using Windows.UI.Xaml.Controls; |
| 16 | + using Windows.UI.Xaml.Navigation; |
22 | 17 |
|
23 | 18 | /// <summary> |
24 | | - /// Provides application-specific behavior to supplement the default Application class. |
| 19 | + /// Defines application-specific behavior to supplement the default Application class. |
25 | 20 | /// </summary> |
26 | 21 | public sealed partial class App : Application |
27 | 22 | { |
28 | | - /// <summary> |
29 | | - /// Initializes the singleton application object. This is the first line of authored code |
30 | | - /// executed, and as such is the logical equivalent of main() or WinMain(). |
31 | | - /// </summary> |
| 23 | + private IServiceProvider serviceProvider; |
| 24 | + |
32 | 25 | public App() |
33 | 26 | { |
34 | 27 | this.InitializeComponent(); |
35 | | - this.Suspending += OnSuspending; |
36 | 28 | } |
37 | 29 |
|
38 | | - public static AppDialog Dialog { get; private set; } |
39 | | - |
40 | | - /// <summary> |
41 | | - /// Invoked when the application is launched normally by the end user. Other entry points |
42 | | - /// will be used such as when the application is launched to open a specific file. |
43 | | - /// </summary> |
44 | | - /// <param name="e">Details about the launch request and process.</param> |
45 | | - protected override void OnLaunched(LaunchActivatedEventArgs e) |
| 30 | + public static IServiceProvider Services |
46 | 31 | { |
47 | | -#if DEBUG |
48 | | - if (System.Diagnostics.Debugger.IsAttached) |
| 32 | + get |
49 | 33 | { |
50 | | - // this.DebugSettings.EnableFrameRateCounter = true; |
| 34 | + IServiceProvider serviceProvider = ((App)Current).serviceProvider; |
| 35 | + |
| 36 | + if (serviceProvider is null) |
| 37 | + { |
| 38 | + throw new InvalidOperationException("Service provider is not initialized."); |
| 39 | + } |
| 40 | + |
| 41 | + return serviceProvider; |
51 | 42 | } |
52 | | -#endif |
| 43 | + } |
| 44 | + |
| 45 | + |
| 46 | + protected override async void OnLaunched(LaunchActivatedEventArgs e) |
| 47 | + { |
| 48 | + await this.ActivateAsync(e.PrelaunchActivated); |
| 49 | + } |
| 50 | + |
| 51 | + protected override async void OnActivated(IActivatedEventArgs args) |
| 52 | + { |
| 53 | + await this.ActivateAsync(false); |
| 54 | + } |
| 55 | + |
| 56 | + private static IServiceProvider ConfigureServices(Frame rootFrame) |
| 57 | + { |
| 58 | + Ioc.Default.ConfigureServices( |
| 59 | + new ServiceCollection() |
| 60 | + .AddSingleton<IMessenger>(provider => WeakReferenceMessenger.Default) |
| 61 | + .AddSingleton<IEventLogger, FileEventLogger>() |
| 62 | + .AddSingleton<IAppDiagnostics, AppDiagnostics>() |
| 63 | + .AddSingleton<INavigationService>(provider => new NavigationService(rootFrame)) |
| 64 | + .AddViewModels() |
| 65 | + .BuildServiceProvider()); |
| 66 | + |
| 67 | + return Ioc.Default; |
| 68 | + } |
53 | 69 |
|
| 70 | + private static void OnNavigationFailed(object sender, NavigationFailedEventArgs e) |
| 71 | + { |
| 72 | + throw new InvalidOperationException($"Failed to load page {e.SourcePageType.FullName}."); |
| 73 | + } |
| 74 | + |
| 75 | + private async Task ActivateAsync(bool isPrelaunch) |
| 76 | + { |
54 | 77 | #if NET5_0 && WINDOWS |
55 | 78 | var window = new Window(); |
56 | 79 | window.Activate(); |
57 | 80 | #else |
58 | | - var window = Windows.UI.Xaml.Window.Current; |
| 81 | + Window window = Windows.UI.Xaml.Window.Current; |
59 | 82 | #endif |
60 | 83 |
|
61 | | - Frame rootFrame = window.Content as Frame; |
62 | | - |
63 | | - // Do not repeat app initialization when the Window already has content, |
64 | | - // just ensure that the window is active |
65 | | - if (rootFrame == null) |
| 84 | + if (!(window.Content is Frame rootFrame)) |
66 | 85 | { |
67 | | - // Create a Frame to act as the navigation context and navigate to the first page |
68 | 86 | rootFrame = new Frame(); |
69 | | - |
70 | 87 | rootFrame.NavigationFailed += OnNavigationFailed; |
71 | 88 |
|
72 | | - if (e.PreviousExecutionState == ApplicationExecutionState.Terminated) |
| 89 | + window.Content = rootFrame; |
| 90 | + |
| 91 | + this.serviceProvider = ConfigureServices(rootFrame); |
| 92 | + |
| 93 | + IAppDiagnostics diagnostics = this.serviceProvider.GetService<IAppDiagnostics>(); |
| 94 | + if (diagnostics != null) |
73 | 95 | { |
74 | | - //TODO: Load state from previously suspended application |
| 96 | + await diagnostics.StartRecordingDiagnosticsAsync(); |
75 | 97 | } |
76 | | - |
77 | | - // Place the frame in the current Window |
78 | | - window.Content = rootFrame; |
79 | 98 | } |
80 | 99 |
|
81 | | - Dialog = new AppDialog(rootFrame.Dispatcher); |
82 | | - |
83 | | -#if !(NET5_0 && WINDOWS) |
84 | | - if (e.PrelaunchActivated == false) |
85 | | -#endif |
| 100 | + if (!isPrelaunch) |
86 | 101 | { |
87 | | - if (rootFrame.Content == null) |
| 102 | + if (rootFrame.Content is null) |
88 | 103 | { |
89 | | - // When the navigation stack isn't restored navigate to the first page, |
90 | | - // configuring the new page by passing required information as a navigation |
91 | | - // parameter |
92 | | - rootFrame.Navigate(typeof(MainPage), e.Arguments); |
| 104 | + rootFrame.Navigate(typeof(MainPage)); |
93 | 105 | } |
94 | | - // Ensure the current window is active |
| 106 | + |
95 | 107 | window.Activate(); |
96 | 108 | } |
97 | 109 | } |
98 | | - |
99 | | - /// <summary> |
100 | | - /// Invoked when Navigation to a certain page fails |
101 | | - /// </summary> |
102 | | - /// <param name="sender">The Frame which failed navigation</param> |
103 | | - /// <param name="e">Details about the navigation failure</param> |
104 | | - void OnNavigationFailed(object sender, NavigationFailedEventArgs e) |
105 | | - { |
106 | | - throw new Exception($"Failed to load {e.SourcePageType.FullName}: {e.Exception}"); |
107 | | - } |
108 | | - |
109 | | - /// <summary> |
110 | | - /// Invoked when application execution is being suspended. Application state is saved |
111 | | - /// without knowing whether the application will be terminated or resumed with the contents |
112 | | - /// of memory still intact. |
113 | | - /// </summary> |
114 | | - /// <param name="sender">The source of the suspend request.</param> |
115 | | - /// <param name="e">Details about the suspend request.</param> |
116 | | - private void OnSuspending(object sender, SuspendingEventArgs e) |
117 | | - { |
118 | | - var deferral = e.SuspendingOperation.GetDeferral(); |
119 | | - //TODO: Save application state and stop any background activity |
120 | | - deferral.Complete(); |
121 | | - } |
122 | 110 | } |
123 | 111 | } |
0 commit comments