Skip to content

Instantly share code, notes, and snippets.

@bitbonk
Last active August 31, 2019 23:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bitbonk/89f2a5f998860788d27ada46cd6e613b to your computer and use it in GitHub Desktop.
Save bitbonk/89f2a5f998860788d27ada46cd6e613b to your computer and use it in GitHub Desktop.
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