using GFramework.Core.system;
namespace GFramework.Core.ioc;
///
/// IOC容器类,用于管理对象的注册和获取
///
public class IocContainer
{
///
/// 核心存储结构:
/// 一个 Type 对应 0~N 个实例
///
private readonly Dictionary> _instances = new();
#region Register
///
/// 注册单例(强语义)
/// 一个类型只允许一个实例
///
/// 要注册为单例的类型
/// 要注册的单例实例
/// 当该类型已经注册过单例时抛出异常
public void RegisterSingleton(T instance)
{
var type = typeof(T);
if (_instances.TryGetValue(type, out var list) && list.Count > 0)
{
throw new InvalidOperationException(
$"Singleton already registered for type: {type.Name}");
}
_instances[type] = [instance!];
}
///
/// 注册多个接口实现,并将其实例同时绑定到其所有匹配的接口上
///
/// 基类型或接口类型
/// 具体的实例对象
public void RegisterPlurality(T instance)
{
var concreteType = instance!.GetType();
Register(concreteType, instance);
// 获取实例类型实现的所有接口,并筛选出可以赋值给T类型的接口
var interfaces = concreteType.GetInterfaces()
.Where(typeof(T).IsAssignableFrom);
foreach (var itf in interfaces)
{
Register(itf, instance);
}
}
///
/// 注册系统实例,将其绑定到其所有实现的接口上
///
/// 系统实例对象
public void RegisterSystem(ISystem system)
{
RegisterPlurality(system);
}
///
/// 注册实例(自动支持多实例)
///
/// 要注册的实例的类型
/// 要注册的实例
public void Register(T instance)
{
Register(typeof(T), instance!);
}
///
/// 按指定类型注册实例
/// (常用于 interface / base type)
///
/// 要注册的目标类型
/// 要注册的实例
public void Register(Type type, object instance)
{
if (!_instances.TryGetValue(type, out var list))
{
list = [];
_instances[type] = list;
}
// 防止重复注册同一个实例
if (!list.Contains(instance))
{
list.Add(instance);
}
}
#endregion
#region Get
///
/// 获取单个实例(通常用于具体类型)
/// 如果存在多个,只返回第一个
///
/// 期望获取的实例类型
/// 找到的第一个实例;如果未找到则返回 null
public T? Get() where T : class
{
var type = typeof(T);
// 尝试从实例字典中获取指定类型的实例列表
if (_instances.TryGetValue(type, out var list) && list.Count > 0)
{
return list[0] as T;
}
return null;
}
///
/// 获取指定类型的必需实例
///
/// 期望获取的实例类型
/// 找到的唯一实例
/// 当没有注册实例或注册了多个实例时抛出
public T GetRequired() where T : class
{
var list = GetAll();
// 根据实例数量进行判断和处理
return list.Count switch
{
0 => throw new InvalidOperationException($"No instance registered for {typeof(T).Name}"),
> 1 => throw new InvalidOperationException($"Multiple instances registered for {typeof(T).Name}"),
_ => list[0]
};
}
///
/// 获取指定类型的所有实例(接口 / 抽象类推荐使用)
///
/// 期望获取的实例类型
/// 所有符合条件的实例列表;如果没有则返回空数组
public IReadOnlyList GetAll() where T : class
{
var type = typeof(T);
if (_instances.TryGetValue(type, out var list))
{
return list.Cast().ToList();
}
return Array.Empty();
}
///
/// 获取并排序(系统调度专用)
///
/// 期望获取的实例类型
/// 比较器委托,定义排序规则
/// 按指定方式排序后的实例列表
public IReadOnlyList GetAllSorted(Comparison comparison)
where T : class
{
var list = GetAll().ToList();
list.Sort(comparison);
return list;
}
#endregion
#region Utility
///
/// 是否已注册指定类型
///
/// 要检查是否注册的类型
/// 若该类型已被注册则返回 true,否则返回 false
public bool Contains()
{
return _instances.ContainsKey(typeof(T));
}
///
/// 清空容器
///
public void Clear()
{
_instances.Clear();
}
#endregion
}