using System; using System.Reflection; using System.Collections.Generic; using System.Linq; using Microsoft.Xna.Framework; using System.Diagnostics; using Barotrauma; namespace QIDependencyInjection { /// /// Stores type mapping and creates injected objects with GetService. /// It works as both ServiceCollection and ServiceProvider from /// Microsoft.Extensions.QIDependencyInjection /// public partial class ServiceCollection { /// /// Safety guard for potential infinite loops /// public static int MaxRecursionDepth = 10; /// /// Method with this name will be called after injecting all props /// public static string AfterInjectMethodName = "AfterInject"; /// /// Method with this name will be called after injecting all static props /// public static string AfterInjectStaticMethodName = "AfterInjectStatic"; /// /// If true it will log actions to console /// public bool Debug { get; set; } /// /// Single instances for types. /// If target type maps to a singleton it will be used instead of a new instance /// public Dictionary Singletons = new(); /// /// The type mapping. /// If target type also in the mapping then collection will /// recursivelly resolve target type until it reaches the end. /// If there's a loop it will warn you /// public Dictionary Mapping = new(); /// /// Just clears all data /// public void Clear() { Singletons.Clear(); Mapping.Clear(); } /// /// Returns final type that chain of mappings is pointing to /// /// /// public Type GetTargetType() => GetTargetType(typeof(ServiceType)); public Type GetTargetType(Type ServiceType) { if (!Mapping.ContainsKey(ServiceType)) return ServiceType; int depth = 0; Type TargetType = Mapping[ServiceType]; if (TargetType == ServiceType) return TargetType; while (Mapping.ContainsKey(TargetType)) { ServiceType = TargetType; TargetType = Mapping[ServiceType]; if (TargetType == ServiceType) return TargetType; if (depth++ > MaxRecursionDepth) { Log($"ServiceCollection: There seems to be a loop in your mapping", Color.Orange); Log($"Can't find target type for {ServiceType}", Color.Orange); return null; } } return TargetType; } public string WrapInColor(object msg, string color) => $"‖color:{color}‖{msg}‖end‖"; public static void Log(object msg, Color? color = null) { color ??= new Color(128, 255, 128); LuaCsLogger.LogMessage($"{msg ?? "null"}", color * 0.8f, color); } public void Info(object msg, Color? color = null) { if (Debug == true) Log(msg, color); } /// /// Will print Mapping and Singletons to console if Debug == true /// public void PrintState() { if (!Debug) return; Log("--------------------------------- Mapping ----------------------------------"); foreach (var (s, i) in Mapping) Log($"{s.Name} -> {i.Name}"); Log("--------------------------------- Singletons --------------------------------"); foreach (var (i, o) in Singletons) Log($"{o}({o.GetHashCode()})"); Log("------------------------------------------------------------------------------"); } } }