feat(ioc): 替换自定义IoC容器为Microsoft.Extensions.DependencyInjection

- 移除原有的IocContainer实现
- 添加MicrosoftDiContainer作为Microsoft.Extensions.DependencyInjection的适配器
- 修改ArchitectureServices使用MicrosoftDiContainer替代IocContainer
- 更新所有相关测试类使用MicrosoftDiContainer
- 添加Mediator和Microsoft.Extensions.DependencyInjection包引用
- 扩展IIocContainer接口支持更多注册方法
- 在架构初始化中添加Mediator服务注册
This commit is contained in:
GeWuYou 2026-02-14 10:06:17 +08:00 committed by gewuyou
parent 68d292dc64
commit 55ec42a670
15 changed files with 576 additions and 476 deletions

View File

@ -25,5 +25,6 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Mediator.Abstractions" Version="3.0.1"/>
</ItemGroup>
</Project>

View File

@ -1,5 +1,6 @@
using GFramework.Core.Abstractions.rule;
using GFramework.Core.Abstractions.system;
using Microsoft.Extensions.DependencyInjection;
namespace GFramework.Core.Abstractions.ioc;
@ -19,6 +20,14 @@ public interface IIocContainer : IContextAware
/// <exception cref="InvalidOperationException">当该类型已经注册过单例时抛出异常</exception>
void RegisterSingleton<T>(T instance);
/// <summary>
/// 注册单例服务,指定服务类型和实现类型
/// 创建单例实例并在容器中注册
/// </summary>
/// <typeparam name="TService">服务接口或基类类型</typeparam>
/// <typeparam name="TImpl">具体的实现类型</typeparam>
void RegisterSingleton<TService, TImpl>()
where TImpl : class, TService where TService : class;
/// <summary>
/// 注册多个实例
@ -47,6 +56,14 @@ public interface IIocContainer : IContextAware
/// <param name="instance">要注册的实例对象</param>
void Register(Type type, object instance);
/// <summary>
/// 注册工厂方法来创建服务实例
/// 通过委托函数动态创建服务实例
/// </summary>
/// <typeparam name="TService">服务类型</typeparam>
/// <param name="factory">创建服务实例的工厂委托函数</param>
void RegisterFactory<TService>(Func<IServiceProvider, TService> factory);
#endregion
#region Get Methods
@ -117,7 +134,7 @@ public interface IIocContainer : IContextAware
/// </summary>
/// <typeparam name="T">要检查的类型</typeparam>
/// <returns>如果容器中包含指定类型的实例则返回true否则返回false</returns>
bool Contains<T>();
bool Contains<T>() where T : class;
/// <summary>
/// 判断容器中是否包含某个具体的实例对象
@ -133,8 +150,16 @@ public interface IIocContainer : IContextAware
/// <summary>
/// 冻结容器,防止后续修改
/// 调用此方法后,容器将变为只读状态,不能再注册新的服务实例
/// </summary>
void Freeze();
/// <summary>
/// 获取底层的服务集合
/// 提供对内部IServiceCollection的访问权限用于高级配置和自定义操作
/// </summary>
/// <returns>底层的IServiceCollection实例</returns>
IServiceCollection Services { get; }
#endregion
}

View File

@ -46,13 +46,13 @@ public class ArchitectureContextTests
[SetUp]
public void SetUp()
{
// 初始化 LoggerFactoryResolver 以支持 IocContainer
// 初始化 LoggerFactoryResolver 以支持 MicrosoftDiContainer
LoggerFactoryResolver.Provider = new ConsoleLoggerFactoryProvider();
_container = new IocContainer();
_container = new MicrosoftDiContainer();
// 直接初始化 logger 字段
var loggerField = typeof(IocContainer).GetField("_logger",
var loggerField = typeof(MicrosoftDiContainer).GetField("_logger",
BindingFlags.NonPublic | BindingFlags.Instance);
loggerField?.SetValue(_container,
LoggerFactoryResolver.Provider.CreateLogger(nameof(ArchitectureContextTests)));
@ -75,7 +75,7 @@ public class ArchitectureContextTests
}
private ArchitectureContext? _context;
private IocContainer? _container;
private MicrosoftDiContainer? _container;
private EventBus? _eventBus;
private CommandExecutor? _commandBus;
private QueryExecutor? _queryBus;

View File

@ -59,7 +59,7 @@ public class ArchitectureServicesTests
public void Container_Should_Be_Instance_Of_IocContainer()
{
Assert.That(_services!.Container, Is.InstanceOf<IIocContainer>());
Assert.That(_services.Container, Is.InstanceOf<IocContainer>());
Assert.That(_services.Container, Is.InstanceOf<MicrosoftDiContainer>());
}
/// <summary>
@ -218,7 +218,7 @@ public class ArchitectureServicesTests
public class TestArchitectureContextV3 : IArchitectureContext
{
private readonly IocContainer _container = new();
private readonly MicrosoftDiContainer _container = new();
private readonly DefaultEnvironment _environment = new();
public int Id { get; init; }

View File

@ -229,7 +229,7 @@ public class TestArchitecture : Architecture
/// </summary>
public class TestArchitectureContext : IArchitectureContext
{
private readonly IocContainer _container = new();
private readonly MicrosoftDiContainer _container = new();
/// <summary>
/// 获取依赖注入容器

View File

@ -32,7 +32,7 @@ public class AbstractAsyncCommandTests
[SetUp]
public void SetUp()
{
_container = new IocContainer();
_container = new MicrosoftDiContainer();
_container.RegisterPlurality(new EventBus());
_container.RegisterPlurality(new CommandExecutor());
_container.RegisterPlurality(new QueryExecutor());
@ -42,7 +42,7 @@ public class AbstractAsyncCommandTests
}
private ArchitectureContext _context = null!;
private IocContainer _container = null!;
private MicrosoftDiContainer _container = null!;
/// <summary>
/// 测试异步命令无返回值版本的基础实现

View File

@ -10,7 +10,7 @@ namespace GFramework.Core.Tests.ioc;
/// 测试 IoC 容器功能的单元测试类
/// </summary>
[TestFixture]
public class IocContainerTests
public class MicrosoftDiContainerTests
{
/// <summary>
/// 在每个测试方法执行前进行设置
@ -18,18 +18,18 @@ public class IocContainerTests
[SetUp]
public void SetUp()
{
// 初始化 LoggerFactoryResolver 以支持 IocContainer
// 初始化 LoggerFactoryResolver 以支持 MicrosoftDiContainer
LoggerFactoryResolver.Provider = new ConsoleLoggerFactoryProvider();
_container = new IocContainer();
_container = new MicrosoftDiContainer();
// 直接初始化 logger 字段
var loggerField = typeof(IocContainer).GetField("_logger",
var loggerField = typeof(MicrosoftDiContainer).GetField("_logger",
BindingFlags.NonPublic | BindingFlags.Instance);
loggerField?.SetValue(_container,
LoggerFactoryResolver.Provider.CreateLogger(nameof(IocContainer)));
LoggerFactoryResolver.Provider.CreateLogger(nameof(MicrosoftDiContainer)));
}
private IocContainer _container = null!;
private MicrosoftDiContainer _container = null!;
private readonly Dictionary<Type, object> _mockContextServices = new();
/// <summary>

View File

@ -30,7 +30,7 @@ public class AbstractAsyncQueryTests
[SetUp]
public void SetUp()
{
_container = new IocContainer();
_container = new MicrosoftDiContainer();
_container.RegisterPlurality(new EventBus());
_container.RegisterPlurality(new CommandExecutor());
_container.RegisterPlurality(new QueryExecutor());
@ -40,7 +40,7 @@ public class AbstractAsyncQueryTests
}
private ArchitectureContext _context = null!;
private IocContainer _container = null!;
private MicrosoftDiContainer _container = null!;
/// <summary>
/// 测试异步查询的基础实现

View File

@ -37,14 +37,14 @@ public class StateMachineSystemTests
[SetUp]
public void SetUp()
{
// 初始化 LoggerFactoryResolver 以支持 IocContainer
// 初始化 LoggerFactoryResolver 以支持 MicrosoftDiContainer
LoggerFactoryResolver.Provider = new ConsoleLoggerFactoryProvider();
_eventBus = new EventBus();
var container = new IocContainer();
var container = new MicrosoftDiContainer();
// 直接初始化 logger 字段
var loggerField = typeof(IocContainer).GetField("_logger",
var loggerField = typeof(MicrosoftDiContainer).GetField("_logger",
BindingFlags.NonPublic | BindingFlags.Instance);
loggerField?.SetValue(container,
LoggerFactoryResolver.Provider.CreateLogger(nameof(StateMachineSystemTests)));

View File

@ -30,7 +30,7 @@ public class AbstractContextUtilityTests
[SetUp]
public void SetUp()
{
_container = new IocContainer();
_container = new MicrosoftDiContainer();
_container.RegisterPlurality(new EventBus());
_container.RegisterPlurality(new CommandExecutor());
_container.RegisterPlurality(new QueryExecutor());
@ -40,7 +40,7 @@ public class AbstractContextUtilityTests
}
private ArchitectureContext _context = null!;
private IocContainer _container = null!;
private MicrosoftDiContainer _container = null!;
/// <summary>
/// 测试AbstractContextUtility实现IContextUtility接口

View File

@ -12,5 +12,11 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="LanguageExt.Core" Version="4.4.9"/>
<PackageReference Include="Mediator.Abstractions" Version="3.0.1"/>
<PackageReference Include="Mediator.SourceGenerator" Version="3.0.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.3"/>
</ItemGroup>
</Project>

View File

@ -10,6 +10,7 @@ using GFramework.Core.Abstractions.utility;
using GFramework.Core.environment;
using GFramework.Core.extensions;
using GFramework.Core.logging;
using Microsoft.Extensions.DependencyInjection;
using IDisposable = GFramework.Core.Abstractions.lifecycle.IDisposable;
namespace GFramework.Core.architecture;
@ -540,6 +541,9 @@ public abstract class Architecture(
// 为服务设置上下文
Services.SetContext(_context);
// 添加 Mediator
Container.Services.AddMediator();
// === 用户 Init ===
_logger.Debug("Calling user Init()");
Init();

View File

@ -47,7 +47,7 @@ public class ArchitectureServices : IArchitectureServices
/// </summary>
public ArchitectureServices()
{
Container = new IocContainer();
Container = new MicrosoftDiContainer();
// 创建服务实例
_eventBus = new EventBus();

View File

@ -1,452 +0,0 @@
using GFramework.Core.Abstractions.ioc;
using GFramework.Core.Abstractions.logging;
using GFramework.Core.Abstractions.system;
using GFramework.Core.logging;
using GFramework.Core.rule;
namespace GFramework.Core.ioc;
/// <summary>
/// IOC容器类用于管理对象的注册和获取
/// </summary>
public class IocContainer : ContextAwareBase, IIocContainer
{
#region Lock
/// <summary>
/// 读写锁对象,用于控制多线程环境下对共享资源的访问
/// 使用ReaderWriterLockSlim提供高效的读写锁定机制
/// 配置为不支持递归锁,避免死锁风险
/// </summary>
private readonly ReaderWriterLockSlim _lock = new(LockRecursionPolicy.NoRecursion);
#endregion
#region Flag
/// <summary>
/// 冻结标志位,用于标识对象是否已被冻结
/// true表示对象已冻结不可修改false表示对象可正常修改
/// </summary>
private volatile bool _frozen;
#endregion
#region Core
/// <summary>
/// 存储所有已注册对象实例的集合,用于跟踪和管理容器中的所有对象
/// 使用HashSet确保对象唯一性避免重复注册同一实例
/// </summary>
private readonly HashSet<object> _objects = [];
/// <summary>
/// 类型索引字典,用于快速查找指定类型的所有实例
/// 键为类型对象,值为该类型对应的所有实例集合
/// </summary>
private readonly Dictionary<Type, HashSet<object>> _typeIndex = new();
private ILogger _logger = null!;
#endregion
#region Register
/// <summary>
/// 当上下文准备就绪时调用此方法,用于初始化日志记录器。
/// </summary>
protected override void OnContextReady()
{
// 创建日志记录器实例并将其赋值给_logger字段
_logger =
LoggerFactoryResolver.Provider.CreateLogger(nameof(IocContainer));
}
/// <summary>
/// 注册单例
/// 一个类型只允许一个实例
/// </summary>
/// <typeparam name="T">要注册为单例的类型</typeparam>
/// <param name="instance">要注册的单例实例</param>
/// <exception cref="InvalidOperationException">当该类型已经注册过单例时抛出异常</exception>
public void RegisterSingleton<T>(T instance)
{
var type = typeof(T);
_lock.EnterWriteLock();
try
{
// 检查容器是否已被冻结
if (_frozen)
{
var errorMsg = "IocContainer is frozen";
_logger.Error(errorMsg);
throw new InvalidOperationException(errorMsg);
}
// 检查该类型是否已经注册过单例
if (_typeIndex.TryGetValue(type, out var set) && set.Count > 0)
{
var errorMsg = $"Singleton already registered for type: {type.Name}";
_logger.Error(errorMsg);
throw new InvalidOperationException(errorMsg);
}
RegisterInternal(type, instance!);
_logger.Debug($"Singleton registered: {type.Name}");
}
finally
{
_lock.ExitWriteLock();
}
}
/// <summary>
/// 注册多个实例
/// 将实例注册到其实现的所有接口和具体类型上
/// </summary>
/// <param name="instance">要注册的实例</param>
public void RegisterPlurality(object instance)
{
var concreteType = instance.GetType();
var interfaces = concreteType.GetInterfaces();
_lock.EnterWriteLock();
try
{
// 注册具体类型
RegisterInternal(concreteType, instance);
// 注册所有接口类型
foreach (var itf in interfaces) RegisterInternal(itf, instance);
}
finally
{
_lock.ExitWriteLock();
}
}
/// <summary>
/// 在内部字典中注册指定类型和实例的映射关系
/// </summary>
/// <param name="type">要注册的类型</param>
/// <param name="instance">要注册的实例</param>
private void RegisterInternal(Type type, object instance)
{
if (_frozen)
{
const string errorMsg = "IocContainer is frozen";
_logger.Error(errorMsg);
throw new InvalidOperationException(errorMsg);
}
_objects.Add(instance);
if (!_typeIndex.TryGetValue(type, out var set))
{
set = [];
_typeIndex[type] = set;
}
set.Add(instance);
}
/// <summary>
/// 注册系统实例,将其绑定到其所有实现的接口上
/// </summary>
/// <param name="system">系统实例对象</param>
public void RegisterSystem(ISystem system)
{
RegisterPlurality(system);
}
/// <summary>
/// 注册指定类型的实例到容器中
/// </summary>
/// <typeparam name="T">要注册的实例类型</typeparam>
/// <param name="instance">要注册的实例对象不能为null</param>
public void Register<T>(T instance)
{
// 获取写锁以确保线程安全
_lock.EnterWriteLock();
try
{
RegisterInternal(typeof(T), instance!);
}
finally
{
// 释放写锁
_lock.ExitWriteLock();
}
}
/// <summary>
/// 注册指定类型的实例到容器中
/// </summary>
/// <param name="type">要注册的实例类型</param>
/// <param name="instance">要注册的实例对象</param>
public void Register(Type type, object instance)
{
// 获取写锁以确保线程安全
_lock.EnterWriteLock();
try
{
RegisterInternal(type, instance);
}
finally
{
// 释放写锁
_lock.ExitWriteLock();
}
}
#endregion
#region Get
/// <summary>
/// 获取单个实例(通常用于具体类型)
/// 如果存在多个,只返回第一个
/// </summary>
/// <typeparam name="T">期望获取的实例类型</typeparam>
/// <returns>找到的第一个实例;如果未找到则返回 null</returns>
public T? Get<T>() where T : class
{
_lock.EnterReadLock();
try
{
if (_typeIndex.TryGetValue(typeof(T), out var set) && set.Count > 0)
{
var result = set.First() as T;
_logger.Debug($"Retrieved instance: {typeof(T).Name}");
return result;
}
_logger.Debug($"No instance found for type: {typeof(T).Name}");
return null;
}
finally
{
_lock.ExitReadLock();
}
}
/// <summary>
/// 获取指定类型的单个实例
/// 如果存在多个,只返回第一个
/// </summary>
/// <param name="type">期望获取的实例类型</param>
/// <returns>找到的第一个实例;如果未找到则返回 null</returns>
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();
}
}
/// <summary>
/// 获取指定类型的必需实例
/// </summary>
/// <typeparam name="T">期望获取的实例类型</typeparam>
/// <returns>找到的唯一实例</returns>
/// <exception cref="InvalidOperationException">当没有注册实例或注册了多个实例时抛出</exception>
public T GetRequired<T>() where T : class
{
var list = GetAll<T>();
switch (list.Count)
{
case 0:
var notFoundMsg = $"No instance registered for {typeof(T).Name}";
_logger.Error(notFoundMsg);
throw new InvalidOperationException(notFoundMsg);
case 1:
_logger.Debug($"Retrieved required instance: {typeof(T).Name}");
return list[0];
default:
var multipleMsg = $"Multiple instances registered for {typeof(T).Name}";
_logger.Error(multipleMsg);
throw new InvalidOperationException(multipleMsg);
}
}
/// <summary>
/// 获取指定类型的必需实例
/// </summary>
/// <param name="type">期望获取的实例类型</param>
/// <returns>找到的唯一实例</returns>
/// <exception cref="InvalidOperationException">当没有注册实例或注册了多个实例时抛出</exception>
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);
}
}
/// <summary>
/// 获取指定类型的所有实例(接口 / 抽象类推荐使用)
/// </summary>
/// <typeparam name="T">期望获取的实例类型</typeparam>
/// <returns>所有符合条件的实例列表;如果没有则返回空数组</returns>
public IReadOnlyList<T> GetAll<T>() where T : class
{
_lock.EnterReadLock();
try
{
return _typeIndex.TryGetValue(typeof(T), out var set)
? set.Cast<T>().ToList() // 快照
: Array.Empty<T>();
}
finally
{
_lock.ExitReadLock();
}
}
/// <summary>
/// 获取指定类型的所有实例
/// </summary>
/// <param name="type">期望获取的实例类型</param>
/// <returns>所有符合条件的实例列表;如果没有则返回空数组</returns>
public IReadOnlyList<object> GetAll(Type type)
{
_lock.EnterReadLock();
try
{
return _typeIndex.TryGetValue(type, out var set)
? set.ToList() // 快照
: Array.Empty<object>();
}
finally
{
_lock.ExitReadLock();
}
}
/// <summary>
/// 获取并排序(系统调度专用)
/// </summary>
/// <typeparam name="T">期望获取的实例类型</typeparam>
/// <param name="comparison">比较器委托,定义排序规则</param>
/// <returns>按指定方式排序后的实例列表</returns>
public IReadOnlyList<T> GetAllSorted<T>(Comparison<T> comparison)
where T : class
{
var list = GetAll<T>().ToList();
list.Sort(comparison);
return list;
}
#endregion
#region Utility
/// <summary>
/// 检查容器中是否包含指定类型的实例
/// </summary>
/// <typeparam name="T">要检查的类型</typeparam>
/// <returns>如果容器中包含指定类型的实例则返回true否则返回false</returns>
public bool Contains<T>()
{
_lock.EnterReadLock();
try
{
return _typeIndex.TryGetValue(typeof(T), out var set) && set.Count > 0;
}
finally
{
_lock.ExitReadLock();
}
}
/// <summary>
/// 清空容器中的所有实例
/// </summary>
public void Clear()
{
_lock.EnterWriteLock();
try
{
_objects.Clear();
_typeIndex.Clear();
}
finally
{
_lock.ExitWriteLock();
}
}
/// <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>
public void Freeze()
{
// 获取写锁以确保线程安全的状态修改
_lock.EnterWriteLock();
try
{
_frozen = true;
_logger.Info("IOC Container frozen - no further registrations allowed");
}
finally
{
_lock.ExitWriteLock();
}
}
#endregion
}

View File

@ -0,0 +1,516 @@
using GFramework.Core.Abstractions.ioc;
using GFramework.Core.Abstractions.logging;
using GFramework.Core.Abstractions.system;
using GFramework.Core.logging;
using GFramework.Core.rule;
using Microsoft.Extensions.DependencyInjection;
namespace GFramework.Core.ioc;
/// <summary>
/// Microsoft.Extensions.DependencyInjection 适配器
/// 将 Microsoft DI 包装为 IIocContainer 接口实现
/// 提供线程安全的依赖注入容器功能
/// </summary>
/// <param name="serviceCollection">可选的IServiceCollection实例默认创建新的ServiceCollection</param>
public class MicrosoftDiContainer(IServiceCollection? serviceCollection = null) : ContextAwareBase, IIocContainer
{
#region Context Ready
/// <summary>
/// 上下文准备就绪时的回调方法
/// 初始化日志记录器实例
/// </summary>
protected override void OnContextReady()
{
_logger = LoggerFactoryResolver.Provider.CreateLogger(nameof(MicrosoftDiContainer));
}
#endregion
#region Fields
/// <summary>
/// 服务提供者,在容器冻结后构建,用于解析服务实例
/// </summary>
private IServiceProvider? _provider;
/// <summary>
/// 容器冻结状态标志true表示容器已冻结不可修改
/// </summary>
private volatile bool _frozen;
/// <summary>
/// 读写锁,确保多线程环境下的线程安全操作
/// </summary>
private readonly ReaderWriterLockSlim _lock = new(LockRecursionPolicy.NoRecursion);
/// <summary>
/// 已注册实例的集合,用于快速检查实例是否存在
/// </summary>
private readonly HashSet<object> _registeredInstances = [];
/// <summary>
/// 日志记录器,用于记录容器操作日志
/// </summary>
private ILogger _logger = null!;
#endregion
#region Register
/// <summary>
/// 注册单例服务实例
/// 确保同一类型只能注册一次,避免重复注册
/// </summary>
/// <typeparam name="T">服务类型</typeparam>
/// <param name="instance">要注册的实例对象</param>
/// <exception cref="InvalidOperationException">当容器已冻结或类型已被注册时抛出</exception>
public void RegisterSingleton<T>(T instance)
{
var type = typeof(T);
_lock.EnterWriteLock();
try
{
ThrowIfFrozen();
// 检查是否已注册该类型,防止重复注册
if (Services.Any(s => s.ServiceType == type))
{
var errorMsg = $"Singleton already registered for type: {type.Name}";
_logger.Error(errorMsg);
throw new InvalidOperationException(errorMsg);
}
Services.AddSingleton(type, instance!);
_registeredInstances.Add(instance!);
_logger.Debug($"Singleton registered: {type.Name}");
}
finally
{
_lock.ExitWriteLock();
}
}
/// <summary>
/// 注册单例服务,指定服务类型和实现类型
/// 直接使用底层DI容器注册类型映射关系
/// </summary>
/// <typeparam name="TService">服务接口或基类类型</typeparam>
/// <typeparam name="TImpl">具体的实现类型</typeparam>
public void RegisterSingleton<TService, TImpl>()
where TImpl : class, TService where TService : class
{
Services.AddSingleton<TService, TImpl>();
}
/// <summary>
/// 注册多个实例到其所有接口和具体类型
/// 实现一个实例支持多种接口类型的解析
/// </summary>
/// <param name="instance">要注册的对象实例</param>
/// <exception cref="InvalidOperationException">当容器已冻结时抛出</exception>
public void RegisterPlurality(object instance)
{
var concreteType = instance.GetType();
var interfaces = concreteType.GetInterfaces();
_lock.EnterWriteLock();
try
{
ThrowIfFrozen();
// 注册具体类型映射
Services.AddSingleton(concreteType, instance);
// 注册所有接口类型映射(指向同一实例)
foreach (var interfaceType in interfaces)
{
Services.AddSingleton(interfaceType, _ => instance);
}
_registeredInstances.Add(instance);
_logger.Debug($"Plurality registered: {concreteType.Name} with {interfaces.Length} interfaces");
}
finally
{
_lock.ExitWriteLock();
}
}
/// <summary>
/// 注册系统实例
/// 通过RegisterPlurality方法注册ISystem类型实例
/// </summary>
/// <param name="system">要注册的系统实例</param>
public void RegisterSystem(ISystem system)
{
RegisterPlurality(system);
}
/// <summary>
/// 注册指定泛型类型的服务实例
/// </summary>
/// <typeparam name="T">服务类型</typeparam>
/// <param name="instance">要注册的实例对象</param>
/// <exception cref="InvalidOperationException">当容器已冻结时抛出</exception>
public void Register<T>(T instance)
{
_lock.EnterWriteLock();
try
{
ThrowIfFrozen();
Services.AddSingleton(typeof(T), instance!);
_registeredInstances.Add(instance!);
_logger.Debug($"Registered: {typeof(T).Name}");
}
finally
{
_lock.ExitWriteLock();
}
}
/// <summary>
/// 注册指定类型的服务实例
/// </summary>
/// <param name="type">服务类型</param>
/// <param name="instance">要注册的实例对象</param>
/// <exception cref="InvalidOperationException">当容器已冻结时抛出</exception>
public void Register(Type type, object instance)
{
_lock.EnterWriteLock();
try
{
ThrowIfFrozen();
Services.AddSingleton(type, instance);
_registeredInstances.Add(instance);
_logger.Debug($"Registered: {type.Name}");
}
finally
{
_lock.ExitWriteLock();
}
}
/// <summary>
/// 注册工厂方法来创建服务实例
/// 通过委托函数动态创建服务实例,支持依赖注入
/// </summary>
/// <typeparam name="TService">服务类型</typeparam>
/// <param name="factory">创建服务实例的工厂委托函数接收IServiceProvider参数</param>
public void RegisterFactory<TService>(Func<IServiceProvider, TService> factory)
{
ThrowIfFrozen();
Services.AddSingleton(factory);
}
#endregion
#region Get
/// <summary>
/// 获取指定泛型类型的服务实例
/// 返回第一个匹配的注册实例如果不存在则返回null
/// </summary>
/// <typeparam name="T">服务类型</typeparam>
/// <returns>服务实例或null</returns>
/// <exception cref="InvalidOperationException">当容器未冻结时抛出</exception>
public T? Get<T>() where T : class
{
EnsureProvider();
_lock.EnterReadLock();
try
{
var result = _provider!.GetService<T>();
_logger.Debug(result != null
? $"Retrieved instance: {typeof(T).Name}"
: $"No instance found for type: {typeof(T).Name}");
return result;
}
finally
{
_lock.ExitReadLock();
}
}
/// <summary>
/// 获取指定类型的服务实例
/// 返回第一个匹配的注册实例如果不存在则返回null
/// </summary>
/// <param name="type">服务类型</param>
/// <returns>服务实例或null</returns>
/// <exception cref="InvalidOperationException">当容器未冻结时抛出</exception>
public object? Get(Type type)
{
EnsureProvider();
_lock.EnterReadLock();
try
{
var result = _provider!.GetService(type);
_logger.Debug(result != null
? $"Retrieved instance: {type.Name}"
: $"No instance found for type: {type.Name}");
return result;
}
finally
{
_lock.ExitReadLock();
}
}
/// <summary>
/// 获取指定泛型类型的必需服务实例
/// 必须存在且唯一,否则抛出异常
/// </summary>
/// <typeparam name="T">服务类型</typeparam>
/// <returns>唯一的服务实例</returns>
/// <exception cref="InvalidOperationException">当实例不存在或多于一个时抛出</exception>
public T GetRequired<T>() where T : class
{
var list = GetAll<T>();
switch (list.Count)
{
case 0:
var notFoundMsg = $"No instance registered for {typeof(T).Name}";
_logger.Error(notFoundMsg);
throw new InvalidOperationException(notFoundMsg);
case 1:
_logger.Debug($"Retrieved required instance: {typeof(T).Name}");
return list[0];
default:
var multipleMsg = $"Multiple instances registered for {typeof(T).Name}";
_logger.Error(multipleMsg);
throw new InvalidOperationException(multipleMsg);
}
}
/// <summary>
/// 获取指定类型的必需服务实例
/// 必须存在且唯一,否则抛出异常
/// </summary>
/// <param name="type">服务类型</param>
/// <returns>唯一的服务实例</returns>
/// <exception cref="InvalidOperationException">当实例不存在或多于一个时抛出</exception>
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);
}
}
/// <summary>
/// 获取指定泛型类型的所有服务实例
/// </summary>
/// <typeparam name="T">服务类型</typeparam>
/// <returns>只读的服务实例列表</returns>
/// <exception cref="InvalidOperationException">当容器未冻结时抛出</exception>
public IReadOnlyList<T> GetAll<T>() where T : class
{
EnsureProvider();
_lock.EnterReadLock();
try
{
var services = _provider!.GetServices<T>().ToList();
_logger.Debug($"Retrieved {services.Count} instances of {typeof(T).Name}");
return services;
}
finally
{
_lock.ExitReadLock();
}
}
/// <summary>
/// 获取指定类型的所有服务实例
/// </summary>
/// <param name="type">服务类型</param>
/// <returns>只读的服务实例列表</returns>
/// <exception cref="InvalidOperationException">当容器未冻结时抛出</exception>
public IReadOnlyList<object> GetAll(Type type)
{
EnsureProvider();
_lock.EnterReadLock();
try
{
var services = _provider!.GetServices(type).ToList();
_logger.Debug($"Retrieved {services.Count} instances of {type.Name}");
return services.Where(o => o != null).Cast<object>().ToList();
}
finally
{
_lock.ExitReadLock();
}
}
/// <summary>
/// 获取并排序指定泛型类型的所有服务实例
/// 主要用于系统调度场景
/// </summary>
/// <typeparam name="T">服务类型</typeparam>
/// <param name="comparison">比较委托,用于定义排序规则</param>
/// <returns>排序后的只读服务实例列表</returns>
public IReadOnlyList<T> GetAllSorted<T>(Comparison<T> comparison) where T : class
{
var list = GetAll<T>().ToList();
list.Sort(comparison);
return list;
}
#endregion
#region Utility
/// <summary>
/// 检查容器中是否包含指定泛型类型的实例
/// 根据容器状态选择不同的检查策略
/// </summary>
/// <typeparam name="T">要检查的类型</typeparam>
/// <returns>true表示包含该类型实例false表示不包含</returns>
public bool Contains<T>() where T : class
{
if (_provider == null)
return Services.Any(s => s.ServiceType == typeof(T));
_lock.EnterReadLock();
try
{
return _provider.GetService<T>() != null;
}
finally
{
_lock.ExitReadLock();
}
}
/// <summary>
/// 判断容器中是否包含某个具体的实例对象
/// 通过已注册实例集合进行快速查找
/// </summary>
/// <param name="instance">要检查的实例对象</param>
/// <returns>true表示包含该实例false表示不包含</returns>
public bool ContainsInstance(object instance)
{
_lock.EnterReadLock();
try
{
return _registeredInstances.Contains(instance);
}
finally
{
_lock.ExitReadLock();
}
}
/// <summary>
/// 清空容器中的所有实例和服务注册
/// 只有在容器未冻结状态下才能执行清空操作
/// </summary>
public void Clear()
{
_lock.EnterWriteLock();
try
{
// 冻结的容器不允许清空操作
if (_frozen)
{
_logger.Warn("Cannot clear frozen container");
return;
}
Services.Clear();
_registeredInstances.Clear();
_provider = null;
_logger.Info("Container cleared");
}
finally
{
_lock.ExitWriteLock();
}
}
/// <summary>
/// 冻结容器并构建ServiceProvider
/// 冻结后容器变为只读状态,不能再注册新服务
/// </summary>
public void Freeze()
{
_lock.EnterWriteLock();
try
{
// 防止重复冻结
if (_frozen)
{
_logger.Warn("Container already frozen");
return;
}
_provider = Services.BuildServiceProvider();
_frozen = true;
_logger.Info("IOC Container frozen - ServiceProvider built");
}
finally
{
_lock.ExitWriteLock();
}
}
/// <summary>
/// 获取底层的服务集合
/// 提供对内部IServiceCollection的访问权限用于高级配置和自定义操作
/// </summary>
/// <returns>底层的IServiceCollection实例</returns>
public IServiceCollection Services { get; } = serviceCollection ?? new ServiceCollection();
#endregion
#region Helper Methods
/// <summary>
/// 检查容器是否已冻结,如果已冻结则抛出异常
/// 用于保护注册操作的安全性
/// </summary>
/// <exception cref="InvalidOperationException">当容器已冻结时抛出</exception>
private void ThrowIfFrozen()
{
if (_frozen)
{
const string errorMsg = "MicrosoftDiContainer is frozen";
_logger.Error(errorMsg);
throw new InvalidOperationException(errorMsg);
}
}
/// <summary>
/// 确保ServiceProvider已构建如果未构建则抛出异常
/// 用于保护获取服务操作的安全性
/// </summary>
/// <exception cref="InvalidOperationException">当ServiceProvider未构建时抛出</exception>
private void EnsureProvider()
{
if (_provider == null)
{
throw new InvalidOperationException(
"Container has not been frozen yet. Call Freeze() before retrieving services.");
}
}
#endregion
}