Last active
August 31, 2019 23:56
-
-
Save bitbonk/89f2a5f998860788d27ada46cd6e613b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class MyCaliburnBootstrapper : BootstrapperBase | |
{ | |
private IHost? host; | |
protected MyCaliburnBootstrapper() | |
{ | |
this.Initialize(); | |
} | |
private IHost BuildHost() | |
{ | |
return | |
Host | |
.CreateDefaultBuilder() | |
.ConfigureServices( | |
(context, services) => | |
{ | |
// TODO: add your services here | |
})) | |
.UseWpfApplicationLifetime() | |
.Build(); | |
} | |
protected override async void Configure() | |
{ | |
this.host = this.BuildHost(); | |
await this.host.RunAsync(); | |
} | |
protected override IEnumerable<object> GetAllInstances(Type service) | |
{ | |
if (this.host == null) | |
{ | |
throw new InvalidOperationException("Host is not created"); | |
} | |
return this.host.Services.GetServices(service); | |
} | |
protected override object GetInstance(Type service, string key) | |
{ | |
if (this.host == null) | |
{ | |
throw new InvalidOperationException("Host is not created"); | |
} | |
return this.host.Services.GetRequiredService(service); | |
} | |
} | |
public static class WpfApplicationLifetimeHostBuilderExtensions | |
{ | |
public static IHostBuilder UseWpfApplicationLifetime(this IHostBuilder hostBuilder) | |
{ | |
return hostBuilder.ConfigureServices( | |
(context, collection) => collection.AddSingleton<IHostLifetime, WpfApplicationLifetime>()); | |
} | |
} | |
public class WpfApplicationLifetime : IHostLifetime, IDisposable | |
{ | |
private readonly ManualResetEvent shutdownBlock = new ManualResetEvent(false); | |
private readonly WpfApplicationLifetimeOptions options; | |
private readonly IHostEnvironment environment; | |
private readonly IHostApplicationLifetime applicationLifetime; | |
private readonly ILogger logger; | |
private CancellationTokenRegistration applicationStartedRegistration; | |
private CancellationTokenRegistration applicationStoppingRegistration; | |
public WpfApplicationLifetime( | |
IOptions<WpfApplicationLifetimeOptions> options, | |
IHostEnvironment environment, | |
IHostApplicationLifetime applicationLifetime, | |
ILoggerFactory loggerFactory) | |
{ | |
if (loggerFactory == null) | |
{ | |
throw new ArgumentNullException(nameof(loggerFactory)); | |
} | |
this.options = options?.Value ?? throw new ArgumentNullException(nameof(options)); | |
this.environment = environment ?? throw new ArgumentNullException(nameof(environment)); | |
this.applicationLifetime = | |
applicationLifetime ?? throw new ArgumentNullException(nameof(applicationLifetime)); | |
this.logger = loggerFactory.CreateLogger("Microsoft.Hosting.Lifetime"); | |
} | |
public async Task WaitForStartAsync(CancellationToken cancellationToken) | |
{ | |
if (Application.Current == null || Application.Current.Dispatcher == null) | |
{ | |
throw new InvalidOperationException($"The {typeof(Application)} is not initialized"); | |
} | |
var tcs = new TaskCompletionSource<bool>(); | |
if (Application.Current.Dispatcher.CheckAccess()) | |
{ | |
AttachToApplicationStartup(); | |
} | |
else | |
{ | |
Application.Current.Dispatcher.Invoke(AttachToApplicationStartup); | |
} | |
AppDomain.CurrentDomain.ProcessExit += this.OnProcessExit; | |
if (!this.options.SuppressStatusMessages) | |
{ | |
this.applicationStartedRegistration = this.applicationLifetime.ApplicationStarted.Register( | |
state => ((WpfApplicationLifetime)state).OnApplicationStarted(), | |
this); | |
this.applicationStoppingRegistration = this.applicationLifetime.ApplicationStopping.Register( | |
state => ((WpfApplicationLifetime)state).OnApplicationStopping(), | |
this); | |
} | |
await tcs.Task; | |
void AttachToApplicationStartup() | |
{ | |
Application.Current.Startup += (sender, args) => tcs.SetResult(true); | |
} | |
} | |
public void Dispose() | |
{ | |
this.Dispose(true); | |
GC.SuppressFinalize(this); | |
} | |
public Task StopAsync(CancellationToken cancellationToken) | |
{ | |
return Task.CompletedTask; | |
} | |
protected virtual void Dispose(bool disposing) | |
{ | |
if (disposing) | |
{ | |
this.shutdownBlock.Set(); | |
this.applicationStartedRegistration.Dispose(); | |
this.applicationStoppingRegistration.Dispose(); | |
} | |
} | |
private void OnProcessExit(object sender, EventArgs e) | |
{ | |
this.applicationLifetime.StopApplication(); | |
this.shutdownBlock.WaitOne(); | |
} | |
private void OnApplicationStarted() | |
{ | |
this.logger.LogInformation("Application started."); | |
this.logger.LogInformation("Hosting environment: {envName}", (object)this.environment.EnvironmentName); | |
this.logger.LogInformation("Content root path: {contentRoot}", (object)this.environment.ContentRootPath); | |
} | |
private void OnApplicationStopping() | |
{ | |
this.logger.LogInformation("Application is shutting down..."); | |
} | |
} | |
public class WpfApplicationLifetimeOptions | |
{ | |
public bool SuppressStatusMessages { get; set; } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment