diff --git a/GFramework.Core.Abstractions/GlobalUsings.cs b/GFramework.Core.Abstractions/GlobalUsings.cs index 4d27181..7c0f226 100644 --- a/GFramework.Core.Abstractions/GlobalUsings.cs +++ b/GFramework.Core.Abstractions/GlobalUsings.cs @@ -13,6 +13,7 @@ global using System; global using System.Collections.Generic; +global using System.Runtime; global using System.Linq; global using System.Threading; global using System.Threading.Tasks; \ No newline at end of file diff --git a/GFramework.Core.Abstractions/ioc/IIocContainer.cs b/GFramework.Core.Abstractions/ioc/IIocContainer.cs index 17e8702..6d8cba4 100644 --- a/GFramework.Core.Abstractions/ioc/IIocContainer.cs +++ b/GFramework.Core.Abstractions/ioc/IIocContainer.cs @@ -59,6 +59,15 @@ public interface IIocContainer : IContextAware /// 找到的第一个实例;如果未找到则返回 null T? Get() where T : class; + /// + /// 根据指定类型获取单个实例 + /// 如果存在多个,只返回第一个 + /// + /// 期望获取的实例类型 + /// 找到的第一个实例;如果未找到则返回 null + object? Get(Type type); + + /// /// 获取指定类型的必需实例 /// @@ -67,6 +76,15 @@ public interface IIocContainer : IContextAware /// 当没有注册实例或注册了多个实例时抛出 T GetRequired() where T : class; + /// + /// 获取指定类型的必需实例 + /// + /// 期望获取的实例类型 + /// 找到的唯一实例 + /// 当没有注册实例或注册了多个实例时抛出 + object GetRequired(Type type); + + /// /// 获取指定类型的所有实例(接口 / 抽象类推荐使用) /// @@ -74,6 +92,14 @@ public interface IIocContainer : IContextAware /// 所有符合条件的实例列表;如果没有则返回空数组 IReadOnlyList GetAll() where T : class; + /// + /// 获取指定类型的所有实例 + /// + /// 期望获取的实例类型 + /// 所有符合条件的实例列表;如果没有则返回空数组 + IReadOnlyList GetAll(Type type); + + /// /// 获取并排序(系统调度专用) /// diff --git a/GFramework.Core/ioc/IocContainer.cs b/GFramework.Core/ioc/IocContainer.cs index 164a8d4..5f4bf9d 100644 --- a/GFramework.Core/ioc/IocContainer.cs +++ b/GFramework.Core/ioc/IocContainer.cs @@ -233,6 +233,33 @@ public class IocContainer : ContextAwareBase, IIocContainer } } + /// + /// 获取指定类型的单个实例 + /// 如果存在多个,只返回第一个 + /// + /// 期望获取的实例类型 + /// 找到的第一个实例;如果未找到则返回 null + public object? Get(Type type) + { + _lock.EnterReadLock(); + try + { + if (_typeIndex.TryGetValue(type, out var set) && set.Count > 0) + { + var result = set.First(); + _logger.Debug($"Retrieved instance: {type.Name}"); + return result; + } + + _logger.Debug($"No instance found for type: {type.Name}"); + return null; + } + finally + { + _lock.ExitReadLock(); + } + } + /// /// 获取指定类型的必需实例 @@ -262,6 +289,34 @@ public class IocContainer : ContextAwareBase, IIocContainer } } + /// + /// 获取指定类型的必需实例 + /// + /// 期望获取的实例类型 + /// 找到的唯一实例 + /// 当没有注册实例或注册了多个实例时抛出 + public object GetRequired(Type type) + { + var list = GetAll(type); + + switch (list.Count) + { + case 0: + var notFoundMsg = $"No instance registered for {type.Name}"; + _logger.Error(notFoundMsg); + throw new InvalidOperationException(notFoundMsg); + + case 1: + _logger.Debug($"Retrieved required instance: {type.Name}"); + return list[0]; + + default: + var multipleMsg = $"Multiple instances registered for {type.Name}"; + _logger.Error(multipleMsg); + throw new InvalidOperationException(multipleMsg); + } + } + /// /// 获取指定类型的所有实例(接口 / 抽象类推荐使用) /// @@ -282,6 +337,26 @@ public class IocContainer : ContextAwareBase, IIocContainer } } + /// + /// 获取指定类型的所有实例 + /// + /// 期望获取的实例类型 + /// 所有符合条件的实例列表;如果没有则返回空数组 + public IReadOnlyList GetAll(Type type) + { + _lock.EnterReadLock(); + try + { + return _typeIndex.TryGetValue(type, out var set) + ? set.ToList() // 快照 + : Array.Empty(); + } + finally + { + _lock.ExitReadLock(); + } + } + /// /// 获取并排序(系统调度专用)