using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.Threading.Tasks;

namespace MyDemo
{
 public sealed class Host
 {
  #region Singleton

  /// <summary>
  /// Static constructor
  /// </summary>
  static Host()
  {
   Current = new Host();
  }

  /// <summary>
  /// current instance
  /// </summary>
  public static Host Current { get; }

  #endregion

  #region Declarations

  private readonly IHost _host;

  #endregion

  #region Constructor / Services

  /// <summary>
  /// Constructor
  /// </summary>
  private Host()
  {
   _host = new HostBuilder()
    .ConfigureServices(ConfigureServices)
    .Build();
  }

  /// <summary>
  /// Configure services
  /// </summary>
  /// <param name="context"></param>
  /// <param name="services"></param>
  private void ConfigureServices(HostBuilderContext context, IServiceCollection services)
  {
   // Add ViewsModels, Views, services
   services.AddTransient<IMainViewModel, MainViewModel>();
   services.AddTransient<IMainView, MainView>();
   services.AddTransient<ISettingsViewModel, SettingsViewModel>();
   services.AddTransient<ISettingsView, SettingsView>();
   services.AddTransient<INavigationService, NavigationService>();
  }

  #endregion

  #region Methodes

  /// <summary>
  /// Start the host
  /// </summary>
  /// <returns></returns>
  public async Task StartAsync()
  {
   await _host.StartAsync();
  }

  /// <summary>
  /// Stop the host
  /// </summary>
  /// <returns></returns>
  public async Task StopAsync()
  {
   await _host.StopAsync();
   _host.Dispose();
  }

  /// <summary>
  /// Get an instance of service of type T
  /// </summary>
  /// <typeparam name="T"></typeparam>
  /// <returns></returns>
  public T GetService<T>()
  {
   return _host.Services.GetService<T>();            
  }

  #endregion
 }
}

protected override async void OnLaunched(LaunchActivatedEventArgs e)
{
 // Host
 if (e.PrelaunchActivated == false)
 {
  await Host.Current.StartAsync();
 }
 // ...
}

public partial class App : Application
{
 private async void Application_Startup(object sender, StartupEventArgs e)
 {
  await Host.Current.StartAsync();
  MainWindow = Host.Current.GetService<MainView>();
  MainWindow.Show();
 }

 private async void Application_Exit(object sender, ExitEventArgs e)
 {
  await Host.Current.StopAsync();
 }
}

private static T GetSettings<T>()
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json", optional: false);

    var config = builder.Build();
    var settings = config.Get<T>();
    return settings;
}