using System.Reflection; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Speckle.Connectors.Common.Threading; using Speckle.Connectors.DUI.Bindings; using Speckle.Connectors.DUI.Bridge; using Speckle.Connectors.DUI.Models; using Speckle.Sdk; using Speckle.Sdk.Common; using Speckle.Sdk.Transports; namespace Speckle.Connectors.DUI; public static class ContainerRegistration { public static void AddDUI(this IServiceCollection serviceCollection) where TDocumentStore : DocumentModelStore where TThreadContext : IThreadContext, new() { // context always newed up on host app's main/ui thread serviceCollection.AddSingleton(new TThreadContext()); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(sp => sp.GetService()); serviceCollection.AddTransient(); // POC: Each binding should have it's own bridge instance serviceCollection.AddMatchingInterfacesAsTransient(Assembly.GetAssembly(typeof(IdleCallManager)).NotNull()); serviceCollection.AddMatchingInterfacesAsTransient(Assembly.GetAssembly(typeof(IServerTransportFactory)).NotNull()); serviceCollection.AddSingleton(sp => sp.GetRequiredService() ); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); } public static void UseDUI(this IServiceProvider serviceProvider) { //observe the unobserved! TaskScheduler.UnobservedTaskException += (_, args) => { try { foreach (var exception in args.Exception.InnerExceptions) { if (TestAndLogStacktrace(serviceProvider, exception)) { args.SetObserved(); } } } #pragma warning disable CA1031 catch (Exception e) #pragma warning restore CA1031 { Console.WriteLine("Error logging unobserved task exception"); Console.WriteLine(args.Exception); Console.WriteLine(e); } }; } private static bool TestAndLogStacktrace(IServiceProvider serviceProvider, Exception exception) { var stackTrace = exception.ToString(); if (stackTrace.IndexOf("Speckle", StringComparison.InvariantCultureIgnoreCase) <= 0) { serviceProvider .GetRequiredService() .CreateLogger("UnobservedTaskException") .LogInformation(exception, "Non-Speckle unobserved task exception"); return false; } serviceProvider .GetRequiredService() .CreateLogger("UnobservedTaskException") .LogError(exception, "Unobserved task exception"); return true; } }