From b86add9789f4aef230df4ee698ad3f15d08d5757 Mon Sep 17 00:00:00 2001 From: GwWuYou <95328647+GeWuYou@users.noreply.github.com> Date: Wed, 17 Dec 2025 22:06:31 +0800 Subject: [PATCH] =?UTF-8?q?refactor(ioc):=20=E9=87=8D=E6=9E=84IocContainer?= =?UTF-8?q?=E4=BB=A5=E6=94=AF=E6=8C=81=E5=A4=9A=E5=AE=9E=E4=BE=8B=E5=92=8C?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E6=B3=A8=E5=86=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修改核心存储结构为Dictionary>以支持多实例 - 新增RegisterSingleton方法用于注册单例实例 - 新增RegisterPlurality方法用于注册多个接口实现 - 新增RegisterSystem方法用于注册系统实例 - 新增GetAll方法获取指定类型的所有实例 - 新增GetRequired方法获取必需的唯一实例 - 新增GetAllSorted方法支持实例排序 - 新增Contains方法检查类型是否已注册 - 新增Clear方法清空容器 - 完善异常处理和重复注册检查 --- GFramework.Core/ioc/IocContainer.cs | 185 +++++++++++++++++++++++++--- 1 file changed, 171 insertions(+), 14 deletions(-) diff --git a/GFramework.Core/ioc/IocContainer.cs b/GFramework.Core/ioc/IocContainer.cs index 824abcc..d15661e 100644 --- a/GFramework.Core/ioc/IocContainer.cs +++ b/GFramework.Core/ioc/IocContainer.cs @@ -1,3 +1,5 @@ +using GFramework.Core.system; + namespace GFramework.Core.ioc; /// @@ -5,32 +7,187 @@ namespace GFramework.Core.ioc; /// public class IocContainer { - private readonly Dictionary _mInstances = new(); + /// + /// 核心存储结构: + /// 一个 Type 对应 0~N 个实例 + /// + private readonly Dictionary> _instances = new(); + + #region Register /// - /// 注册一个实例到IOC容器中 + /// 注册单例(强语义) + /// 一个类型只允许一个实例 /// - /// 实例的类型 - /// 要注册的实例对象 - public void Register(T instance) + /// 要注册为单例的类型 + /// 要注册的单例实例 + /// 当该类型已经注册过单例时抛出异常 + public void RegisterSingleton(T instance) { - var key = typeof(T); + var type = typeof(T); - _mInstances[key] = instance; + if (_instances.TryGetValue(type, out var list) && list.Count > 0) + { + throw new InvalidOperationException( + $"Singleton already registered for type: {type.Name}"); + } + + _instances[type] = new List { instance! }; } /// - /// 从IOC容器中获取指定类型的实例 + /// 注册多个接口实现,并将其实例同时绑定到其所有匹配的接口上 /// - /// 要获取的实例类型 - /// 返回指定类型的实例,如果未找到则返回null - public T Get() where T : class + /// 基类型或接口类型 + /// 具体的实例对象 + public void RegisterPlurality(T instance) { - var key = typeof(T); + var concreteType = instance!.GetType(); + Register(concreteType, instance); + // 获取实例类型实现的所有接口,并筛选出可以赋值给T类型的接口 + var interfaces = concreteType.GetInterfaces() + .Where(typeof(T).IsAssignableFrom); + foreach (var itf in interfaces) + { + Register(itf, instance); + } + } - // 尝试从字典中获取实例 - if (_mInstances.TryGetValue(key, out var retInstance)) return retInstance as T; + /// + /// 注册系统实例,将其绑定到其所有实现的接口上 + /// + /// 系统实例对象 + 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 = new 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 } \ No newline at end of file