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("------------------------------------------------------------------------------");
}
}
}