77// <last-date>2020-05-28 15:00</last-date>
88// -----------------------------------------------------------------------
99
10+ using Microsoft . Extensions . Hosting ;
11+
12+
1013namespace OSharp . Wpf . Stylet ;
1114
1215public abstract class ServiceProviderBootstrapper < TRootViewModel > : BootstrapperBase where TRootViewModel : class
1316{
17+ private IHostBuilder _hostBuilder ;
18+ private IHost _host ;
19+ private readonly CancellationTokenSource _cancellationTokenSource = new ( ) ;
1420 private TRootViewModel _rootViewModel ;
1521 protected virtual TRootViewModel RootViewModel => this . _rootViewModel ??= ( TRootViewModel ) this . GetInstance ( typeof ( TRootViewModel ) ) ;
1622
17- private ServiceProvider _serviceProvider ;
23+ protected IServiceProvider ServiceProvider { get ; private set ; }
1824
19- protected IServiceProvider ServiceProvider => _serviceProvider ;
25+ /// <summary>
26+ /// Called on application startup. This occur after this.Args has been assigned, but before the IoC container has been configured
27+ /// </summary>
28+ protected override void OnStart ( )
29+ {
30+ _hostBuilder = Host . CreateDefaultBuilder ( ) ;
31+ }
2032
2133 /// <summary>
2234 /// Overridden from BootstrapperBase, this sets up the IoC container
2335 /// </summary>
2436 protected override void ConfigureBootstrapper ( )
2537 {
26- IServiceCollection services = new ServiceCollection ( ) ;
27-
28- // Call DefaultConfigureIoC *after* ConfigureIoIC, so that they can customize builder.Assemblies
29- this . DefaultConfigureIoC ( services ) ;
30- this . ConfigureIoC ( services ) ;
31-
32- _serviceProvider = services . BuildServiceProvider ( ) ;
38+ _hostBuilder . ConfigureServices ( ( context , services ) =>
39+ {
40+ services . AddSingleton ( context ) ;
41+ DefaultConfigureIoC ( services ) ;
42+ ConfigureIoC ( services ) ;
43+ } ) ;
44+ _host = _hostBuilder . Build ( ) ;
45+ ServiceProvider = _host . Services ;
46+ _host . StartAsync ( _cancellationTokenSource . Token ) . GetAwaiter ( ) . GetResult ( ) ;
3347 }
3448
3549 protected virtual void ConfigureIoC ( IServiceCollection services )
@@ -40,7 +54,7 @@ protected virtual void DefaultConfigureIoC(IServiceCollection services)
4054 var viewManagerConfig = new ViewManagerConfig ( )
4155 {
4256 ViewFactory = this . GetInstance ,
43- ViewAssemblies = new List < Assembly > ( ) { this . GetType ( ) . Assembly }
57+ ViewAssemblies = new List < Assembly > ( ) { this . GetType ( ) . Assembly }
4458 } ;
4559
4660 services . AddSingleton < IViewManager > ( new ViewManager ( viewManagerConfig ) ) ;
@@ -72,13 +86,39 @@ public override object GetInstance(Type type)
7286 return ServiceProvider ? . GetService ( type ) ;
7387 }
7488
89+ /// <summary>Hook called on application exit</summary>
90+ /// <param name="e">The exit event data</param>
91+ protected override void OnExit ( ExitEventArgs e )
92+ {
93+ base . OnExit ( e ) ;
94+ // 在应用程序退出时停止 host
95+ _cancellationTokenSource . Cancel ( ) ;
96+ try
97+ {
98+ _host ? . StopAsync ( ) . GetAwaiter ( ) . GetResult ( ) ;
99+ }
100+ catch ( Exception ex )
101+ {
102+ // 记录日志但不阻止退出
103+ System . Diagnostics . Debug . WriteLine ( $ "Error stopping host during exit: { ex . Message } ") ;
104+ }
105+ }
106+
75107 /// <summary>
76108 /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
77109 /// </summary>
78110 public override void Dispose ( )
79111 {
80112 base . Dispose ( ) ;
113+ try
114+ {
115+ _host ? . StopAsync ( ) . GetAwaiter ( ) . GetResult ( ) ;
116+ }
117+ finally
118+ {
119+ _host ? . Dispose ( ) ;
120+ _cancellationTokenSource . Dispose ( ) ;
121+ }
81122 ScreenExtensions . TryDispose ( _rootViewModel ) ;
82- _serviceProvider ? . Dispose ( ) ;
83123 }
84124}
0 commit comments