using Serilog; using Splat; using System.Collections.Generic; using System.Linq; namespace SPTInstaller.Helpers; /// /// A helper class to handle simple service registration to Splat with constructor parameter injection /// /// Splat only recognizes the registered types and doesn't account for interfaces :( internal static class ServiceHelper { private static bool TryRegisterInstance(object[] parameters = null) { var instance = Activator.CreateInstance(typeof(T2), parameters); if (instance != null) { Locator.CurrentMutable.RegisterConstant((T)instance); return true; } return false; } /// /// Register a class as a service /// /// class to register public static void Register() where T : class => Register(); /// /// Register a class as a service by another type /// /// type to register as /// class to register public static void Register() where T : class { var constructors = typeof(T2).GetConstructors(); foreach (var constructor in constructors) { var parmesan = constructor.GetParameters(); if (parmesan.Length == 0) { if (TryRegisterInstance()) return; continue; } List parameters = new List(); for (int i = 0; i < parmesan.Length; i++) { var parm = parmesan[i]; var parmValue = Get(parm.ParameterType); if (parmValue != null) parameters.Add(parmValue); } if (TryRegisterInstance(parameters.ToArray())) return; } } /// /// Get a service from splat /// /// /// /// Thrown if the service isn't found public static object Get(Type type) { var service = Locator.Current.GetService(type); if (service == null) { var message = $"Could not locate service of type '{type.Name}'"; Log.Error(message); throw new InvalidOperationException(message); } return service; } /// /// Get a service from splat /// /// /// /// Thrown if the service isn't found public static T Get() { var service = Locator.Current.GetService(); if (service == null) { var message = $"Could not locate service of type '{nameof(T)}'"; Log.Error(message); throw new InvalidOperationException(message); } return service; } /// /// Get all services of a type /// /// /// /// thrown if no services are found public static T[] GetAll() { var services = Locator.Current.GetServices().ToArray(); if (services == null || services.Count() == 0) { var message = $"Could not locate service of type '{nameof(T)}'"; Log.Error(message); throw new InvalidOperationException(message); } return services; } }