mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-24 20:34:29 +08:00
refactor(ioc): 重构IoC容器核心数据结构
- 将_instances字典的值类型从List<object>改为HashSet<object> - 新增_objects集合用于跟踪所有已注册的对象实例 - 修改RegisterSingleton方法实现,添加容器冻结检查 - 优化RegisterInternal方法,避免重复添加相同实例 - 更新GetInstance和GetInstances方法的内部实现逻辑 - 调整Contains和Clear方法以适配新的数据结构 - 新增ContainsInstance方法用于查询具体实例是否存在
This commit is contained in:
parent
1d2847ed5f
commit
f2159065fc
@ -7,11 +7,21 @@ namespace GFramework.Core.ioc;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class IocContainer
|
public class IocContainer
|
||||||
{
|
{
|
||||||
|
#region Core
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 核心存储结构:
|
/// 存储所有已注册对象实例的集合,用于跟踪和管理容器中的所有对象
|
||||||
/// 一个 Type 对应 0~N 个实例
|
/// 使用HashSet确保对象唯一性,避免重复注册同一实例
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly Dictionary<Type, List<object>> _instances = new();
|
private readonly HashSet<object> _objects = [];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 类型索引字典,用于快速查找指定类型的所有实例
|
||||||
|
/// 键为类型对象,值为该类型对应的所有实例集合
|
||||||
|
/// </summary>
|
||||||
|
private readonly Dictionary<Type, HashSet<object>> _typeIndex = new();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Lock
|
#region Lock
|
||||||
|
|
||||||
@ -38,7 +48,7 @@ public class IocContainer
|
|||||||
#region Register
|
#region Register
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 注册单例(强语义)
|
/// 注册单例
|
||||||
/// 一个类型只允许一个实例
|
/// 一个类型只允许一个实例
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">要注册为单例的类型</typeparam>
|
/// <typeparam name="T">要注册为单例的类型</typeparam>
|
||||||
@ -51,13 +61,16 @@ public class IocContainer
|
|||||||
_lock.EnterWriteLock();
|
_lock.EnterWriteLock();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (_instances.TryGetValue(type, out var list) && list.Count > 0)
|
if (_frozen)
|
||||||
|
throw new InvalidOperationException("IocContainer is frozen");
|
||||||
|
|
||||||
|
if (_typeIndex.TryGetValue(type, out var set) && set.Count > 0)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(
|
throw new InvalidOperationException(
|
||||||
$"Singleton already registered for type: {type.Name}");
|
$"Singleton already registered for type: {type.Name}");
|
||||||
}
|
}
|
||||||
|
|
||||||
_instances[type] = [instance!];
|
RegisterInternal(type, instance!);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@ -105,20 +118,19 @@ public class IocContainer
|
|||||||
{
|
{
|
||||||
if (_frozen)
|
if (_frozen)
|
||||||
throw new InvalidOperationException("IocContainer is frozen");
|
throw new InvalidOperationException("IocContainer is frozen");
|
||||||
// 如果该类型还没有对应的实例列表,则创建一个新的列表
|
|
||||||
if (!_instances.TryGetValue(type, out var list))
|
_objects.Add(instance);
|
||||||
|
|
||||||
|
if (!_typeIndex.TryGetValue(type, out var set))
|
||||||
{
|
{
|
||||||
list = [];
|
set = [];
|
||||||
_instances[type] = list;
|
_typeIndex[type] = set;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 避免重复添加相同的实例
|
set.Add(instance);
|
||||||
if (!list.Contains(instance))
|
|
||||||
{
|
|
||||||
list.Add(instance);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 注册系统实例,将其绑定到其所有实现的接口上
|
/// 注册系统实例,将其绑定到其所有实现的接口上
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -184,9 +196,9 @@ public class IocContainer
|
|||||||
_lock.EnterReadLock();
|
_lock.EnterReadLock();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (_instances.TryGetValue(typeof(T), out var list) && list.Count > 0)
|
if (_typeIndex.TryGetValue(typeof(T), out var set) && set.Count > 0)
|
||||||
{
|
{
|
||||||
return list[0] as T;
|
return set.First() as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@ -228,8 +240,8 @@ public class IocContainer
|
|||||||
_lock.EnterReadLock();
|
_lock.EnterReadLock();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return _instances.TryGetValue(typeof(T), out var list)
|
return _typeIndex.TryGetValue(typeof(T), out var set)
|
||||||
? list.Cast<T>().ToList() // 快照
|
? set.Cast<T>().ToList() // 快照
|
||||||
: Array.Empty<T>();
|
: Array.Empty<T>();
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@ -267,7 +279,7 @@ public class IocContainer
|
|||||||
_lock.EnterReadLock();
|
_lock.EnterReadLock();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return _instances.ContainsKey(typeof(T));
|
return _typeIndex.TryGetValue(typeof(T), out var set) && set.Count > 0;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@ -280,11 +292,11 @@ public class IocContainer
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
// 获取写锁以确保线程安全的清空操作
|
|
||||||
_lock.EnterWriteLock();
|
_lock.EnterWriteLock();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_instances.Clear();
|
_objects.Clear();
|
||||||
|
_typeIndex.Clear();
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@ -292,6 +304,25 @@ public class IocContainer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 判断容器中是否包含某个具体的实例对象
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="instance">待查询的实例对象</param>
|
||||||
|
/// <returns>若容器中包含该实例则返回true,否则返回false</returns>
|
||||||
|
public bool ContainsInstance(object instance)
|
||||||
|
{
|
||||||
|
_lock.EnterReadLock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _objects.Contains(instance);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_lock.ExitReadLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 冻结容器,防止后续修改
|
/// 冻结容器,防止后续修改
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user