GFramework/GFramework.Core.Tests/IoC/IocContainerLifetimeTests.cs
GeWuYou fb14d7122c docs(style): 更新文档中的命名空间导入格式
- 将所有小写的命名空间导入更正为首字母大写格式
- 统一 GFramework 框架的命名空间引用规范
- 修复 core、ecs、godot 等模块的命名空间导入错误
- 标准化文档示例代码中的 using 语句格式
- 确保所有文档中的命名空间引用保持一致性
- 更新 global using 语句以匹配正确的命名空间格式
2026-03-10 07:18:49 +08:00

209 lines
6.2 KiB
C#

using GFramework.Core.IoC;
using Microsoft.Extensions.DependencyInjection;
using NUnit.Framework;
namespace GFramework.Core.Tests.IoC;
/// <summary>
/// 测试 IoC 容器生命周期功能
/// </summary>
[TestFixture]
public class IocContainerLifetimeTests
{
private interface ITestService
{
Guid Id { get; }
}
private class TestService : ITestService
{
public Guid Id { get; } = Guid.NewGuid();
}
[Test]
public void RegisterSingleton_Should_Return_Same_Instance()
{
// Arrange
var container = new MicrosoftDiContainer();
container.RegisterSingleton<ITestService, TestService>();
container.Freeze();
// Act
var instance1 = container.Get<ITestService>();
var instance2 = container.Get<ITestService>();
// Assert
Assert.That(instance1, Is.Not.Null);
Assert.That(instance2, Is.Not.Null);
Assert.That(instance1!.Id, Is.EqualTo(instance2!.Id));
}
[Test]
public void RegisterTransient_Should_Return_Different_Instances()
{
// Arrange
var container = new MicrosoftDiContainer();
container.RegisterTransient<ITestService, TestService>();
container.Freeze();
// Act
var instance1 = container.Get<ITestService>();
var instance2 = container.Get<ITestService>();
// Assert
Assert.That(instance1, Is.Not.Null);
Assert.That(instance2, Is.Not.Null);
Assert.That(instance1!.Id, Is.Not.EqualTo(instance2!.Id));
}
[Test]
public void RegisterScoped_Should_Return_Same_Instance_Within_Scope()
{
// Arrange
var container = new MicrosoftDiContainer();
container.RegisterScoped<ITestService, TestService>();
container.Freeze();
// Act
using var scope = container.CreateScope();
var instance1 = scope.ServiceProvider.GetService<ITestService>();
var instance2 = scope.ServiceProvider.GetService<ITestService>();
// Assert
Assert.That(instance1, Is.Not.Null);
Assert.That(instance2, Is.Not.Null);
Assert.That(instance1!.Id, Is.EqualTo(instance2!.Id));
}
[Test]
public void RegisterScoped_Should_Return_Different_Instances_Across_Scopes()
{
// Arrange
var container = new MicrosoftDiContainer();
container.RegisterScoped<ITestService, TestService>();
container.Freeze();
// Act
ITestService? instance1;
ITestService? instance2;
using (var scope1 = container.CreateScope())
{
instance1 = scope1.ServiceProvider.GetService<ITestService>();
}
using (var scope2 = container.CreateScope())
{
instance2 = scope2.ServiceProvider.GetService<ITestService>();
}
// Assert
Assert.That(instance1, Is.Not.Null);
Assert.That(instance2, Is.Not.Null);
Assert.That(instance1!.Id, Is.Not.EqualTo(instance2!.Id));
}
[Test]
public void CreateScope_Should_Throw_When_Container_Not_Frozen()
{
// Arrange
var container = new MicrosoftDiContainer();
container.RegisterScoped<ITestService, TestService>();
// Act & Assert
Assert.Throws<InvalidOperationException>(() => container.CreateScope());
}
[Test]
public void RegisterTransient_Should_Throw_When_Container_Is_Frozen()
{
// Arrange
var container = new MicrosoftDiContainer();
container.Freeze();
// Act & Assert
Assert.Throws<InvalidOperationException>(() =>
container.RegisterTransient<ITestService, TestService>());
}
[Test]
public void RegisterScoped_Should_Throw_When_Container_Is_Frozen()
{
// Arrange
var container = new MicrosoftDiContainer();
container.Freeze();
// Act & Assert
Assert.Throws<InvalidOperationException>(() =>
container.RegisterScoped<ITestService, TestService>());
}
[Test]
public void Mixed_Lifetimes_Should_Work_Together()
{
// Arrange
var container = new MicrosoftDiContainer();
container.RegisterSingleton<ITestService, TestService>();
container.RegisterTransient<ITestService, TestService>();
container.RegisterScoped<ITestService, TestService>();
container.Freeze();
// Act
var singletonInstances = container.GetAll<ITestService>().ToList();
// Assert
Assert.That(singletonInstances.Count, Is.EqualTo(3));
}
[Test]
public void Scoped_Service_Should_Be_Disposed_When_Scope_Disposed()
{
// Arrange
var container = new MicrosoftDiContainer();
container.RegisterScoped<ITestService, TestService>();
container.Freeze();
ITestService? instance;
using (var scope = container.CreateScope())
{
instance = scope.ServiceProvider.GetService<ITestService>();
Assert.That(instance, Is.Not.Null);
}
// Act & Assert - 作用域已释放,实例应该被清理
// 注意:这里只是验证作用域可以正常释放,无法直接验证实例是否被 Dispose
Assert.Pass("Scope disposed successfully");
}
[Test]
public void Multiple_Scopes_Can_Be_Created_Concurrently()
{
// Arrange
var container = new MicrosoftDiContainer();
container.RegisterScoped<ITestService, TestService>();
container.Freeze();
// Act
var scope1 = container.CreateScope();
var scope2 = container.CreateScope();
var scope3 = container.CreateScope();
var instance1 = scope1.ServiceProvider.GetService<ITestService>();
var instance2 = scope2.ServiceProvider.GetService<ITestService>();
var instance3 = scope3.ServiceProvider.GetService<ITestService>();
// Assert
Assert.That(instance1, Is.Not.Null);
Assert.That(instance2, Is.Not.Null);
Assert.That(instance3, Is.Not.Null);
Assert.That(instance1!.Id, Is.Not.EqualTo(instance2!.Id));
Assert.That(instance2!.Id, Is.Not.EqualTo(instance3!.Id));
Assert.That(instance1!.Id, Is.Not.EqualTo(instance3!.Id));
// Cleanup
scope1.Dispose();
scope2.Dispose();
scope3.Dispose();
}
}