From bde1af2c2e6d12bb15a69475eec7be6f87c503b7 Mon Sep 17 00:00:00 2001 From: GeWuYou <95328647+GeWuYou@users.noreply.github.com> Date: Wed, 4 Mar 2026 22:46:50 +0800 Subject: [PATCH] =?UTF-8?q?feat(architecture):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=89=B9=E9=87=8F=E8=8E=B7=E5=8F=96=E7=BB=84=E4=BB=B6=E5=AE=9E?= =?UTF-8?q?=E4=BE=8B=E7=9A=84=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 ArchitectureContext 中添加 GetServices、GetSystems、GetModels 和 GetUtilities 方法 - 扩展 IArchitectureContext 接口以支持批量获取各类组件实例 - 在测试类中实现相应的批量获取功能 - 将原有的 ContextAwareExtensions 拆分为多个专门的扩展类文件 - 新增 ContextAwareCommandExtensions、ContextAwareEnvironmentExtensions 和 ContextAwareEventExtensions 等扩展类 - 提供了更完善的架构上下文组件访问能力 --- .../architecture/IArchitectureContext.cs | 28 ++ .../architecture/ArchitectureServicesTests.cs | 20 + .../architecture/GameContextTests.cs | 40 ++ .../ContextAwareEnvironmentExtensionsTests.cs | 133 +++++ .../rule/ContextAwareEventExtensionsTests.cs | 128 +++++ .../ContextAwareServiceExtensionsTests.cs | 259 ++++++++++ .../architecture/ArchitectureContext.cs | 40 ++ .../ContextAwareCommandExtensions.cs | 113 +++++ .../ContextAwareEnvironmentExtensions.cs | 35 ++ .../extensions/ContextAwareEventExtensions.cs | 70 +++ .../extensions/ContextAwareExtensions.cs | 459 ------------------ .../ContextAwareMediatorExtensions.cs | 125 +++++ .../extensions/ContextAwareQueryExtensions.cs | 81 ++++ .../ContextAwareServiceExtensions.cs | 137 ++++++ 14 files changed, 1209 insertions(+), 459 deletions(-) create mode 100644 GFramework.Core.Tests/rule/ContextAwareEnvironmentExtensionsTests.cs create mode 100644 GFramework.Core.Tests/rule/ContextAwareEventExtensionsTests.cs create mode 100644 GFramework.Core.Tests/rule/ContextAwareServiceExtensionsTests.cs create mode 100644 GFramework.Core/extensions/ContextAwareCommandExtensions.cs create mode 100644 GFramework.Core/extensions/ContextAwareEnvironmentExtensions.cs create mode 100644 GFramework.Core/extensions/ContextAwareEventExtensions.cs delete mode 100644 GFramework.Core/extensions/ContextAwareExtensions.cs create mode 100644 GFramework.Core/extensions/ContextAwareMediatorExtensions.cs create mode 100644 GFramework.Core/extensions/ContextAwareQueryExtensions.cs create mode 100644 GFramework.Core/extensions/ContextAwareServiceExtensions.cs diff --git a/GFramework.Core.Abstractions/architecture/IArchitectureContext.cs b/GFramework.Core.Abstractions/architecture/IArchitectureContext.cs index 496d228..c0d5d05 100644 --- a/GFramework.Core.Abstractions/architecture/IArchitectureContext.cs +++ b/GFramework.Core.Abstractions/architecture/IArchitectureContext.cs @@ -22,6 +22,13 @@ public interface IArchitectureContext /// 服务实例,如果不存在则返回null TService? GetService() where TService : class; + /// + /// 获取指定类型的所有服务实例 + /// + /// 服务类型 + /// 所有符合条件的服务实例列表 + IReadOnlyList GetServices() where TService : class; + /// /// 获取指定类型的系统实例 /// @@ -29,6 +36,13 @@ public interface IArchitectureContext /// 系统实例,如果不存在则返回null TSystem? GetSystem() where TSystem : class, ISystem; + /// + /// 获取指定类型的所有系统实例 + /// + /// 系统类型,必须继承自ISystem接口 + /// 所有符合条件的系统实例列表 + IReadOnlyList GetSystems() where TSystem : class, ISystem; + /// /// 获取指定类型的模型实例 /// @@ -36,6 +50,13 @@ public interface IArchitectureContext /// 模型实例,如果不存在则返回null TModel? GetModel() where TModel : class, IModel; + /// + /// 获取指定类型的所有模型实例 + /// + /// 模型类型,必须继承自IModel接口 + /// 所有符合条件的模型实例列表 + IReadOnlyList GetModels() where TModel : class, IModel; + /// /// 获取指定类型的工具类实例 /// @@ -43,6 +64,13 @@ public interface IArchitectureContext /// 工具类实例,如果不存在则返回null TUtility? GetUtility() where TUtility : class, IUtility; + /// + /// 获取指定类型的所有工具类实例 + /// + /// 工具类类型,必须继承自IUtility接口 + /// 所有符合条件的工具类实例列表 + IReadOnlyList GetUtilities() where TUtility : class, IUtility; + /// /// 发送一个命令 /// diff --git a/GFramework.Core.Tests/architecture/ArchitectureServicesTests.cs b/GFramework.Core.Tests/architecture/ArchitectureServicesTests.cs index 041bfa0..42e2833 100644 --- a/GFramework.Core.Tests/architecture/ArchitectureServicesTests.cs +++ b/GFramework.Core.Tests/architecture/ArchitectureServicesTests.cs @@ -305,21 +305,41 @@ public class TestArchitectureContextV3 : IArchitectureContext return _container.Get(); } + public IReadOnlyList GetServices() where TService : class + { + return _container.GetAll(); + } + public TModel? GetModel() where TModel : class, IModel { return _container.Get(); } + public IReadOnlyList GetModels() where TModel : class, IModel + { + return _container.GetAll(); + } + public TSystem? GetSystem() where TSystem : class, ISystem { return _container.Get(); } + public IReadOnlyList GetSystems() where TSystem : class, ISystem + { + return _container.GetAll(); + } + public TUtility? GetUtility() where TUtility : class, IUtility { return _container.Get(); } + public IReadOnlyList GetUtilities() where TUtility : class, IUtility + { + return _container.GetAll(); + } + public void SendEvent() where TEvent : new() { } diff --git a/GFramework.Core.Tests/architecture/GameContextTests.cs b/GFramework.Core.Tests/architecture/GameContextTests.cs index a3ed70f..93f627f 100644 --- a/GFramework.Core.Tests/architecture/GameContextTests.cs +++ b/GFramework.Core.Tests/architecture/GameContextTests.cs @@ -268,6 +268,16 @@ public class TestArchitectureContext : IArchitectureContext return _container.Get(); } + /// + /// 获取指定类型的所有服务 + /// + /// 服务类型 + /// 所有服务实例列表 + public IReadOnlyList GetServices() where TService : class + { + return _container.GetAll(); + } + /// /// 获取指定类型的模型 /// @@ -278,6 +288,16 @@ public class TestArchitectureContext : IArchitectureContext return _container.Get(); } + /// + /// 获取指定类型的所有模型 + /// + /// 模型类型 + /// 所有模型实例列表 + public IReadOnlyList GetModels() where TModel : class, IModel + { + return _container.GetAll(); + } + /// /// 获取指定类型的系统 /// @@ -288,6 +308,16 @@ public class TestArchitectureContext : IArchitectureContext return _container.Get(); } + /// + /// 获取指定类型的所有系统 + /// + /// 系统类型 + /// 所有系统实例列表 + public IReadOnlyList GetSystems() where TSystem : class, ISystem + { + return _container.GetAll(); + } + /// /// 获取指定类型的工具 /// @@ -298,6 +328,16 @@ public class TestArchitectureContext : IArchitectureContext return _container.Get(); } + /// + /// 获取指定类型的所有工具 + /// + /// 工具类型 + /// 所有工具实例列表 + public IReadOnlyList GetUtilities() where TUtility : class, IUtility + { + return _container.GetAll(); + } + /// /// 发送事件 /// diff --git a/GFramework.Core.Tests/rule/ContextAwareEnvironmentExtensionsTests.cs b/GFramework.Core.Tests/rule/ContextAwareEnvironmentExtensionsTests.cs new file mode 100644 index 0000000..bc2ee5e --- /dev/null +++ b/GFramework.Core.Tests/rule/ContextAwareEnvironmentExtensionsTests.cs @@ -0,0 +1,133 @@ +using GFramework.Core.Abstractions.environment; +using GFramework.Core.Abstractions.rule; +using GFramework.Core.architecture; +using GFramework.Core.extensions; +using GFramework.Core.ioc; +using GFramework.Core.rule; +using NUnit.Framework; + +namespace GFramework.Core.Tests.rule; + +/// +/// 测试 ContextAwareEnvironmentExtensions 的单元测试类 +/// 验证环境对象的获取功能 +/// +[TestFixture] +public class ContextAwareEnvironmentExtensionsTests +{ + [SetUp] + public void SetUp() + { + _container = new MicrosoftDiContainer(); + _context = new ArchitectureContext(_container); + _contextAware = new TestContextAware(); + + ((IContextAware)_contextAware).SetContext(_context); + } + + [TearDown] + public void TearDown() + { + _container.Clear(); + } + + private TestContextAware _contextAware = null!; + private ArchitectureContext _context = null!; + private MicrosoftDiContainer _container = null!; + + [Test] + public void GetEnvironment_Should_Return_Registered_Environment() + { + // Arrange + var environment = new TestEnvironment(); + _container.Register(environment); + _container.Freeze(); + + // Act + var result = _contextAware.GetEnvironment(); + + // Assert + Assert.That(result, Is.SameAs(environment)); + } + + [Test] + public void GetEnvironment_Generic_Should_Return_Typed_Environment() + { + // Arrange + var environment = new TestEnvironment { Name = "TestEnv" }; + _container.Register(environment); + _container.Freeze(); + + // Act + var result = _contextAware.GetEnvironment(); + + // Assert + Assert.That(result, Is.Not.Null); + Assert.That(result, Is.SameAs(environment)); + Assert.That(result!.Name, Is.EqualTo("TestEnv")); + } + + [Test] + public void GetEnvironment_Generic_Should_Return_Null_When_Type_Mismatch() + { + // Arrange + var environment = new TestEnvironment(); + _container.Register(environment); + _container.Freeze(); + + // Act + var result = _contextAware.GetEnvironment(); + + // Assert + Assert.That(result, Is.Null); + } + + private class TestEnvironment : IEnvironment + { + public string Name { get; set; } = string.Empty; + + public T? Get(string key) where T : class => default; + + public bool TryGet(string key, out T value) where T : class + { + value = default!; + return false; + } + + public T GetRequired(string key) where T : class => throw new NotImplementedException(); + + public void Register(string key, object value) + { + } + + public void Initialize() + { + } + } + + private class AnotherEnvironment : IEnvironment + { + public string Name => "Another"; + public T? Get(string key) where T : class => default; + + public bool TryGet(string key, out T value) where T : class + { + value = default!; + return false; + } + + public T GetRequired(string key) where T : class => throw new NotImplementedException(); + + public void Register(string key, object value) + { + } + + public void Initialize() + { + } + } + + private class TestContextAware : ContextAwareBase + { + } +} \ No newline at end of file diff --git a/GFramework.Core.Tests/rule/ContextAwareEventExtensionsTests.cs b/GFramework.Core.Tests/rule/ContextAwareEventExtensionsTests.cs new file mode 100644 index 0000000..25fe848 --- /dev/null +++ b/GFramework.Core.Tests/rule/ContextAwareEventExtensionsTests.cs @@ -0,0 +1,128 @@ +using GFramework.Core.Abstractions.events; +using GFramework.Core.Abstractions.rule; +using GFramework.Core.architecture; +using GFramework.Core.events; +using GFramework.Core.extensions; +using GFramework.Core.ioc; +using GFramework.Core.rule; +using NUnit.Framework; + +namespace GFramework.Core.Tests.rule; + +/// +/// 测试 ContextAwareEventExtensions 的单元测试类 +/// 验证事件发送、注册和取消注册功能 +/// +[TestFixture] +public class ContextAwareEventExtensionsTests +{ + [SetUp] + public void SetUp() + { + _container = new MicrosoftDiContainer(); + _eventBus = new EventBus(); + _container.Register(_eventBus); + _context = new ArchitectureContext(_container); + _contextAware = new TestContextAware(); + + ((IContextAware)_contextAware).SetContext(_context); + _container.Freeze(); + } + + [TearDown] + public void TearDown() + { + _container.Clear(); + } + + private TestContextAware _contextAware = null!; + private ArchitectureContext _context = null!; + private MicrosoftDiContainer _container = null!; + private EventBus _eventBus = null!; + + [Test] + public void SendEvent_Should_Trigger_Registered_Handler() + { + // Arrange + var eventReceived = false; + _contextAware.RegisterEvent(_ => eventReceived = true); + + // Act + _contextAware.SendEvent(new TestEvent()); + + // Assert + Assert.That(eventReceived, Is.True); + } + + [Test] + public void SendEvent_WithNew_Should_Create_And_Send_Event() + { + // Arrange + var eventReceived = false; + _contextAware.RegisterEvent(_ => eventReceived = true); + + // Act + _contextAware.SendEvent(); + + // Assert + Assert.That(eventReceived, Is.True); + } + + [Test] + public void RegisterEvent_Should_Return_UnRegister_Interface() + { + // Act + var unRegister = _contextAware.RegisterEvent(_ => { }); + + // Assert + Assert.That(unRegister, Is.Not.Null); + Assert.That(unRegister, Is.InstanceOf()); + } + + [Test] + public void UnRegisterEvent_Should_Stop_Receiving_Events() + { + // Arrange + var eventCount = 0; + void Handler(TestEvent e) => eventCount++; + + _contextAware.RegisterEvent(Handler); + _contextAware.SendEvent(new TestEvent()); + + // Act + _contextAware.UnRegisterEvent(Handler); + _contextAware.SendEvent(new TestEvent()); + + // Assert + Assert.That(eventCount, Is.EqualTo(1)); + } + + [Test] + public void SendEvent_Should_Pass_Event_Data() + { + // Arrange + TestEvent? receivedEvent = null; + _contextAware.RegisterEvent(e => receivedEvent = e); + var sentEvent = new TestEvent { Data = "TestData" }; + + // Act + _contextAware.SendEvent(sentEvent); + + // Assert + Assert.That(receivedEvent, Is.Not.Null); + Assert.That(receivedEvent!.Data, Is.EqualTo("TestData")); + } + + private class TestEvent + { + public string Data { get; set; } = string.Empty; + } + + private class TestEventWithDefaultConstructor + { + } + + private class TestContextAware : ContextAwareBase + { + } +} \ No newline at end of file diff --git a/GFramework.Core.Tests/rule/ContextAwareServiceExtensionsTests.cs b/GFramework.Core.Tests/rule/ContextAwareServiceExtensionsTests.cs new file mode 100644 index 0000000..75897a2 --- /dev/null +++ b/GFramework.Core.Tests/rule/ContextAwareServiceExtensionsTests.cs @@ -0,0 +1,259 @@ +using GFramework.Core.Abstractions.architecture; +using GFramework.Core.Abstractions.enums; +using GFramework.Core.Abstractions.model; +using GFramework.Core.Abstractions.rule; +using GFramework.Core.Abstractions.system; +using GFramework.Core.Abstractions.utility; +using GFramework.Core.architecture; +using GFramework.Core.extensions; +using GFramework.Core.ioc; +using GFramework.Core.rule; +using NUnit.Framework; + +namespace GFramework.Core.Tests.rule; + +/// +/// 测试 ContextAwareServiceExtensions 的单元测试类 +/// 验证服务、系统、模型、工具的单例和批量获取功能 +/// +[TestFixture] +public class ContextAwareServiceExtensionsTests +{ + [SetUp] + public void SetUp() + { + _container = new MicrosoftDiContainer(); + _context = new ArchitectureContext(_container); + _contextAware = new TestContextAware(); + + ((IContextAware)_contextAware).SetContext(_context); + } + + [TearDown] + public void TearDown() + { + _container.Clear(); + } + + private TestContextAware _contextAware = null!; + private ArchitectureContext _context = null!; + private MicrosoftDiContainer _container = null!; + + [Test] + public void GetService_Should_Return_Registered_Service() + { + // Arrange + var service = new TestService(); + _container.Register(service); + _container.Freeze(); + + // Act + var result = _contextAware.GetService(); + + // Assert + Assert.That(result, Is.SameAs(service)); + } + + [Test] + public void GetSystem_Should_Return_Registered_System() + { + // Arrange + var system = new TestSystem(); + _container.RegisterSystem(system); + _container.Freeze(); + + // Act + var result = _contextAware.GetSystem(); + + // Assert + Assert.That(result, Is.SameAs(system)); + } + + [Test] + public void GetModel_Should_Return_Registered_Model() + { + // Arrange + var model = new TestModel(); + _container.Register(model); + _container.Freeze(); + + // Act + var result = _contextAware.GetModel(); + + // Assert + Assert.That(result, Is.SameAs(model)); + } + + [Test] + public void GetUtility_Should_Return_Registered_Utility() + { + // Arrange + var utility = new TestUtility(); + _container.Register(utility); + _container.Freeze(); + + // Act + var result = _contextAware.GetUtility(); + + // Assert + Assert.That(result, Is.SameAs(utility)); + } + + [Test] + public void GetServices_Should_Return_All_Registered_Services() + { + // Arrange + var service1 = new TestService { Name = "Service1" }; + var service2 = new TestService { Name = "Service2" }; + _container.Register(service1); + _container.Register(service2); + _container.Freeze(); + + // Act + var results = _contextAware.GetServices(); + + // Assert + Assert.That(results, Has.Count.EqualTo(2)); + Assert.That(results, Contains.Item(service1)); + Assert.That(results, Contains.Item(service2)); + } + + [Test] + public void GetSystems_Should_Return_All_Registered_Systems() + { + // Arrange + var system1 = new TestSystem { Name = "System1" }; + var system2 = new TestSystem { Name = "System2" }; + _container.RegisterSystem(system1); + _container.RegisterSystem(system2); + _container.Freeze(); + + // Act + var results = _contextAware.GetSystems(); + + // Assert + Assert.That(results, Has.Count.GreaterThanOrEqualTo(2)); + Assert.That(results.Any(s => s is TestSystem ts && ts.Name == "System1"), Is.True); + Assert.That(results.Any(s => s is TestSystem ts && ts.Name == "System2"), Is.True); + } + + [Test] + public void GetModels_Should_Return_All_Registered_Models() + { + // Arrange + var model1 = new TestModel { Name = "Model1" }; + var model2 = new TestModel { Name = "Model2" }; + _container.Register(model1); + _container.Register(model2); + _container.Freeze(); + + // Act + var results = _contextAware.GetModels(); + + // Assert + Assert.That(results, Has.Count.EqualTo(2)); + Assert.That(results.Any(m => m.Name == "Model1"), Is.True); + Assert.That(results.Any(m => m.Name == "Model2"), Is.True); + } + + [Test] + public void GetUtilities_Should_Return_All_Registered_Utilities() + { + // Arrange + var utility1 = new TestUtility { Name = "Utility1" }; + var utility2 = new TestUtility { Name = "Utility2" }; + _container.Register(utility1); + _container.Register(utility2); + _container.Freeze(); + + // Act + var results = _contextAware.GetUtilities(); + + // Assert + Assert.That(results, Has.Count.EqualTo(2)); + Assert.That(results.Any(u => u.Name == "Utility1"), Is.True); + Assert.That(results.Any(u => u.Name == "Utility2"), Is.True); + } + + [Test] + public void GetServices_Should_Return_Empty_List_When_No_Services_Registered() + { + // Arrange + _container.Freeze(); + + // Act + var results = _contextAware.GetServices(); + + // Assert + Assert.That(results, Is.Empty); + } + + [Test] + public void GetSystems_Should_Return_Empty_List_When_No_Systems_Registered() + { + // Arrange + _container.Freeze(); + + // Act + var results = _contextAware.GetSystems(); + + // Assert + Assert.That(results, Is.Empty); + } + + private class TestService + { + public string Name { get; set; } = string.Empty; + } + + private class TestSystem : ISystem + { + public string Name { get; set; } = string.Empty; + + public void SetContext(IArchitectureContext context) + { + } + + public IArchitectureContext GetContext() => null!; + + public void OnArchitecturePhase(ArchitecturePhase phase) + { + } + + public void Initialize() + { + } + + public void Destroy() + { + } + } + + private class TestModel : IModel + { + public string Name { get; set; } = string.Empty; + + public void SetContext(IArchitectureContext context) + { + } + + public IArchitectureContext GetContext() => null!; + + public void OnArchitecturePhase(ArchitecturePhase phase) + { + } + + public void Initialize() + { + } + } + + private class TestUtility : IUtility + { + public string Name { get; set; } = string.Empty; + } + + private class TestContextAware : ContextAwareBase + { + } +} \ No newline at end of file diff --git a/GFramework.Core/architecture/ArchitectureContext.cs b/GFramework.Core/architecture/ArchitectureContext.cs index 00c36b1..0e8e456 100644 --- a/GFramework.Core/architecture/ArchitectureContext.cs +++ b/GFramework.Core/architecture/ArchitectureContext.cs @@ -233,6 +233,16 @@ public class ArchitectureContext(IIocContainer container) : IArchitectureContext #region Component Retrieval + /// + /// 获取指定类型的所有服务实例 + /// + /// 服务类型 + /// 所有符合条件的服务实例列表 + public IReadOnlyList GetServices() where TService : class + { + return _container.GetAll(); + } + /// /// 从IOC容器中获取指定类型的系统实例 /// @@ -243,6 +253,16 @@ public class ArchitectureContext(IIocContainer container) : IArchitectureContext return GetService(); } + /// + /// 获取指定类型的所有系统实例 + /// + /// 系统类型 + /// 所有符合条件的系统实例列表 + public IReadOnlyList GetSystems() where TSystem : class, ISystem + { + return _container.GetAll(); + } + /// /// 从IOC容器中获取指定类型的模型实例 /// @@ -253,6 +273,16 @@ public class ArchitectureContext(IIocContainer container) : IArchitectureContext return GetService(); } + /// + /// 获取指定类型的所有模型实例 + /// + /// 模型类型 + /// 所有符合条件的模型实例列表 + public IReadOnlyList GetModels() where TModel : class, IModel + { + return _container.GetAll(); + } + /// /// 从IOC容器中获取指定类型的工具实例 /// @@ -263,6 +293,16 @@ public class ArchitectureContext(IIocContainer container) : IArchitectureContext return GetService(); } + /// + /// 获取指定类型的所有工具实例 + /// + /// 工具类型 + /// 所有符合条件的工具实例列表 + public IReadOnlyList GetUtilities() where TUtility : class, IUtility + { + return _container.GetAll(); + } + #endregion #region Command Execution diff --git a/GFramework.Core/extensions/ContextAwareCommandExtensions.cs b/GFramework.Core/extensions/ContextAwareCommandExtensions.cs new file mode 100644 index 0000000..08de9bb --- /dev/null +++ b/GFramework.Core/extensions/ContextAwareCommandExtensions.cs @@ -0,0 +1,113 @@ +using GFramework.Core.Abstractions.command; +using GFramework.Core.Abstractions.rule; + +namespace GFramework.Core.extensions; + +/// +/// 提供对 IContextAware 接口的命令执行扩展方法 +/// +public static class ContextAwareCommandExtensions +{ + /// + /// [Mediator] 发送命令的同步版本(不推荐,仅用于兼容性) + /// + /// 命令响应类型 + /// 实现 IContextAware 接口的对象 + /// 要发送的命令对象 + /// 命令执行结果 + /// 当 contextAware 或 command 为 null 时抛出 + public static TResponse SendCommand(this IContextAware contextAware, + Mediator.ICommand command) + { + ArgumentNullException.ThrowIfNull(contextAware); + ArgumentNullException.ThrowIfNull(command); + + var context = contextAware.GetContext(); + return context.SendCommand(command); + } + + /// + /// 发送一个带返回结果的命令 + /// + /// 命令执行结果类型 + /// 实现 IContextAware 接口的对象 + /// 要发送的命令 + /// 命令执行结果 + /// 当 contextAware 或 command 为 null 时抛出 + public static TResult SendCommand(this IContextAware contextAware, + Abstractions.command.ICommand command) + { + ArgumentNullException.ThrowIfNull(contextAware); + ArgumentNullException.ThrowIfNull(command); + + var context = contextAware.GetContext(); + return context.SendCommand(command); + } + + /// + /// 发送一个无返回结果的命令 + /// + /// 实现 IContextAware 接口的对象 + /// 要发送的命令 + /// 当 contextAware 或 command 为 null 时抛出 + public static void SendCommand(this IContextAware contextAware, Abstractions.command.ICommand command) + { + ArgumentNullException.ThrowIfNull(contextAware); + ArgumentNullException.ThrowIfNull(command); + + var context = contextAware.GetContext(); + context.SendCommand(command); + } + + /// + /// [Mediator] 异步发送命令并返回结果 + /// + /// 命令响应类型 + /// 实现 IContextAware 接口的对象 + /// 要发送的命令对象 + /// 取消令牌,用于取消操作 + /// 包含命令执行结果的ValueTask + /// 当 contextAware 或 command 为 null 时抛出 + public static ValueTask SendCommandAsync(this IContextAware contextAware, + Mediator.ICommand command, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(contextAware); + ArgumentNullException.ThrowIfNull(command); + + var context = contextAware.GetContext(); + return context.SendCommandAsync(command, cancellationToken); + } + + /// + /// 发送并异步执行一个无返回值的命令 + /// + /// 实现 IContextAware 接口的对象 + /// 要发送的命令 + /// 当 contextAware 或 command 为 null 时抛出 + public static async Task SendCommandAsync(this IContextAware contextAware, IAsyncCommand command) + { + ArgumentNullException.ThrowIfNull(contextAware); + ArgumentNullException.ThrowIfNull(command); + + var context = contextAware.GetContext(); + await context.SendCommandAsync(command); + } + + /// + /// 发送并异步执行一个带返回值的命令 + /// + /// 命令执行结果类型 + /// 实现 IContextAware 接口的对象 + /// 要发送的命令 + /// 命令执行结果 + /// 当 contextAware 或 command 为 null 时抛出 + public static async Task SendCommandAsync(this IContextAware contextAware, + IAsyncCommand command) + { + ArgumentNullException.ThrowIfNull(contextAware); + ArgumentNullException.ThrowIfNull(command); + + var context = contextAware.GetContext(); + return await context.SendCommandAsync(command); + } +} \ No newline at end of file diff --git a/GFramework.Core/extensions/ContextAwareEnvironmentExtensions.cs b/GFramework.Core/extensions/ContextAwareEnvironmentExtensions.cs new file mode 100644 index 0000000..333e83a --- /dev/null +++ b/GFramework.Core/extensions/ContextAwareEnvironmentExtensions.cs @@ -0,0 +1,35 @@ +using GFramework.Core.Abstractions.environment; +using GFramework.Core.Abstractions.rule; + +namespace GFramework.Core.extensions; + +/// +/// 提供对 IContextAware 接口的环境访问扩展方法 +/// +public static class ContextAwareEnvironmentExtensions +{ + /// + /// 获取指定类型的环境对象 + /// + /// 要获取的环境对象类型 + /// 上下文感知对象 + /// 指定类型的环境对象,如果无法转换则返回null + public static T? GetEnvironment(this IContextAware contextAware) where T : class + { + ArgumentNullException.ThrowIfNull(contextAware); + var context = contextAware.GetContext(); + return context.GetEnvironment() as T; + } + + /// + /// 获取环境对象 + /// + /// 上下文感知对象 + /// 环境对象 + public static IEnvironment GetEnvironment(this IContextAware contextAware) + { + ArgumentNullException.ThrowIfNull(contextAware); + var context = contextAware.GetContext(); + return context.GetEnvironment(); + } +} \ No newline at end of file diff --git a/GFramework.Core/extensions/ContextAwareEventExtensions.cs b/GFramework.Core/extensions/ContextAwareEventExtensions.cs new file mode 100644 index 0000000..66dc7d8 --- /dev/null +++ b/GFramework.Core/extensions/ContextAwareEventExtensions.cs @@ -0,0 +1,70 @@ +using GFramework.Core.Abstractions.events; +using GFramework.Core.Abstractions.rule; + +namespace GFramework.Core.extensions; + +/// +/// 提供对 IContextAware 接口的事件管理扩展方法 +/// +public static class ContextAwareEventExtensions +{ + /// + /// 发送一个事件 + /// + /// 事件类型 + /// 实现 IContextAware 接口的对象 + /// 当 contextAware 为 null 时抛出 + public static void SendEvent(this IContextAware contextAware) where TEvent : new() + { + ArgumentNullException.ThrowIfNull(contextAware); + var context = contextAware.GetContext(); + context.SendEvent(); + } + + /// + /// 发送一个具体的事件实例 + /// + /// 事件类型 + /// 实现 IContextAware 接口的对象 + /// 事件实例 + /// 当 contextAware 或 e 为 null 时抛出 + public static void SendEvent(this IContextAware contextAware, TEvent e) where TEvent : class + { + ArgumentNullException.ThrowIfNull(contextAware); + ArgumentNullException.ThrowIfNull(e); + + var context = contextAware.GetContext(); + context.SendEvent(e); + } + + /// + /// 注册事件处理器 + /// + /// 事件类型 + /// 实现 IContextAware 接口的对象 + /// 事件处理委托 + /// 事件注销接口 + public static IUnRegister RegisterEvent(this IContextAware contextAware, Action handler) + { + ArgumentNullException.ThrowIfNull(contextAware); + ArgumentNullException.ThrowIfNull(handler); + + var context = contextAware.GetContext(); + return context.RegisterEvent(handler); + } + + /// + /// 取消对某类型事件的监听 + /// + /// 事件类型 + /// 实现 IContextAware 接口的对象 + /// 之前绑定的事件处理器 + public static void UnRegisterEvent(this IContextAware contextAware, Action onEvent) + { + ArgumentNullException.ThrowIfNull(contextAware); + ArgumentNullException.ThrowIfNull(onEvent); + + var context = contextAware.GetContext(); + context.UnRegisterEvent(onEvent); + } +} \ No newline at end of file diff --git a/GFramework.Core/extensions/ContextAwareExtensions.cs b/GFramework.Core/extensions/ContextAwareExtensions.cs deleted file mode 100644 index 50231df..0000000 --- a/GFramework.Core/extensions/ContextAwareExtensions.cs +++ /dev/null @@ -1,459 +0,0 @@ -using GFramework.Core.Abstractions.command; -using GFramework.Core.Abstractions.environment; -using GFramework.Core.Abstractions.events; -using GFramework.Core.Abstractions.model; -using GFramework.Core.Abstractions.query; -using GFramework.Core.Abstractions.rule; -using GFramework.Core.Abstractions.system; -using GFramework.Core.Abstractions.utility; -using Mediator; - -namespace GFramework.Core.extensions; - -/// -/// 提供对 IContextAware 接口的扩展方法 -/// -public static class ContextAwareExtensions -{ - /// - /// 从上下文感知对象中获取指定类型的服务 - /// - /// 要获取的服务类型 - /// 实现 IContextAware 接口的上下文感知对象 - /// 指定类型的服务实例,如果未找到则返回 null - /// 当 contextAware 参数为 null 时抛出 - public static TService? GetService(this IContextAware contextAware) where TService : class - { - ArgumentNullException.ThrowIfNull(contextAware); - var context = contextAware.GetContext(); - return context.GetService(); - } - - /// - /// 获取架构上下文中的指定系统 - /// - /// 目标系统类型 - /// 实现 IContextAware 接口的对象 - /// 指定类型的系统实例 - /// 当 contextAware 为 null 时抛出 - public static TSystem? GetSystem(this IContextAware contextAware) where TSystem : class, ISystem - { - ArgumentNullException.ThrowIfNull(contextAware); - var context = contextAware.GetContext(); - return context.GetSystem(); - } - - - /// - /// 获取架构上下文中的指定模型 - /// - /// 目标模型类型 - /// 实现 IContextAware 接口的对象 - /// 指定类型的模型实例 - /// 当 contextAware 为 null 时抛出 - public static TModel? GetModel(this IContextAware contextAware) where TModel : class, IModel - { - ArgumentNullException.ThrowIfNull(contextAware); - var context = contextAware.GetContext(); - return context.GetModel(); - } - - /// - /// 获取架构上下文中的指定工具 - /// - /// 目标工具类型 - /// 实现 IContextAware 接口的对象 - /// 指定类型的工具实例 - /// 当 contextAware 为 null 时抛出 - public static TUtility? GetUtility(this IContextAware contextAware) where TUtility : class, IUtility - { - ArgumentNullException.ThrowIfNull(contextAware); - var context = contextAware.GetContext(); - return context.GetUtility(); - } - - - /// - /// 发送一个事件 - /// - /// 事件类型 - /// 实现 IContextAware 接口的对象 - /// 当 contextAware 为 null 时抛出 - public static void SendEvent(this IContextAware contextAware) where TEvent : new() - { - ArgumentNullException.ThrowIfNull(contextAware); - var context = contextAware.GetContext(); - context.SendEvent(); - } - - /// - /// 发送一个具体的事件实例 - /// - /// 事件类型 - /// 实现 IContextAware 接口的对象 - /// 事件实例 - /// 当 contextAware 或 e 为 null 时抛出 - public static void SendEvent(this IContextAware contextAware, TEvent e) where TEvent : class - { - ArgumentNullException.ThrowIfNull(contextAware); - ArgumentNullException.ThrowIfNull(e); - - var context = contextAware.GetContext(); - context.SendEvent(e); - } - - /// - /// 注册事件处理器 - /// - /// 事件类型 - /// 实现 IContextAware 接口的对象 - /// 事件处理委托 - /// 事件注销接口 - public static IUnRegister RegisterEvent(this IContextAware contextAware, Action handler) - { - ArgumentNullException.ThrowIfNull(contextAware); - ArgumentNullException.ThrowIfNull(handler); - - var context = contextAware.GetContext(); - return context.RegisterEvent(handler); - } - - /// - /// 取消对某类型事件的监听 - /// - /// 事件类型 - /// 实现 IContextAware 接口的对象 - /// 之前绑定的事件处理器 - public static void UnRegisterEvent(this IContextAware contextAware, Action onEvent) - { - ArgumentNullException.ThrowIfNull(contextAware); - ArgumentNullException.ThrowIfNull(onEvent); - - // 获取上下文对象并取消事件注册 - var context = contextAware.GetContext(); - context.UnRegisterEvent(onEvent); - } - - - /// - /// 获取指定类型的环境对象 - /// - /// 要获取的环境对象类型 - /// 上下文感知对象 - /// 指定类型的环境对象,如果无法转换则返回null - public static T? GetEnvironment(this IContextAware contextAware) where T : class - { - ArgumentNullException.ThrowIfNull(contextAware); - // 获取上下文对象并返回其环境 - var context = contextAware.GetContext(); - return context.GetEnvironment() as T; - } - - /// - /// 获取环境对象 - /// - /// 上下文感知对象 - /// 环境对象 - public static IEnvironment GetEnvironment(this IContextAware contextAware) - { - ArgumentNullException.ThrowIfNull(contextAware); - // 获取上下文对象并返回其环境 - var context = contextAware.GetContext(); - return context.GetEnvironment(); - } - - - /// - /// [Mediator] 发送命令的同步版本(不推荐,仅用于兼容性) - /// - /// 命令响应类型 - /// 实现 IContextAware 接口的对象 - /// 要发送的命令对象 - /// 命令执行结果 - /// 当 contextAware 或 command 为 null 时抛出 - public static TResponse SendCommand(this IContextAware contextAware, - Mediator.ICommand command) - { - ArgumentNullException.ThrowIfNull(contextAware); - ArgumentNullException.ThrowIfNull(command); - - var context = contextAware.GetContext(); - return context.SendCommand(command); - } - - /// - /// 发送一个带返回结果的命令 - /// - /// 命令执行结果类型 - /// 实现 IContextAware 接口的对象 - /// 要发送的命令 - /// 命令执行结果 - /// 当 contextAware 或 command 为 null 时抛出 - public static TResult SendCommand(this IContextAware contextAware, - Abstractions.command.ICommand command) - { - ArgumentNullException.ThrowIfNull(contextAware); - ArgumentNullException.ThrowIfNull(command); - - var context = contextAware.GetContext(); - return context.SendCommand(command); - } - - /// - /// 发送一个无返回结果的命令 - /// - /// 实现 IContextAware 接口的对象 - /// 要发送的命令 - /// 当 contextAware 或 command 为 null 时抛出 - public static void SendCommand(this IContextAware contextAware, Abstractions.command.ICommand command) - { - ArgumentNullException.ThrowIfNull(contextAware); - ArgumentNullException.ThrowIfNull(command); - - var context = contextAware.GetContext(); - context.SendCommand(command); - } - - - /// - /// [Mediator] 异步发送命令并返回结果 - /// - /// 命令响应类型 - /// 实现 IContextAware 接口的对象 - /// 要发送的命令对象 - /// 取消令牌,用于取消操作 - /// 包含命令执行结果的ValueTask - /// 当 contextAware 或 command 为 null 时抛出 - public static ValueTask SendCommandAsync(this IContextAware contextAware, - Mediator.ICommand command, CancellationToken cancellationToken = default) - { - ArgumentNullException.ThrowIfNull(contextAware); - ArgumentNullException.ThrowIfNull(command); - - var context = contextAware.GetContext(); - return context.SendCommandAsync(command, cancellationToken); - } - - /// - /// 发送并异步执行一个无返回值的命令 - /// - /// 实现 IContextAware 接口的对象 - /// 要发送的命令 - /// 当 contextAware 或 command 为 null 时抛出 - public static async Task SendCommandAsync(this IContextAware contextAware, IAsyncCommand command) - { - ArgumentNullException.ThrowIfNull(contextAware); - ArgumentNullException.ThrowIfNull(command); - - var context = contextAware.GetContext(); - await context.SendCommandAsync(command); - } - - /// - /// 发送并异步执行一个带返回值的命令 - /// - /// 命令执行结果类型 - /// 实现 IContextAware 接口的对象 - /// 要发送的命令 - /// 命令执行结果 - /// 当 contextAware 或 command 为 null 时抛出 - public static async Task SendCommandAsync(this IContextAware contextAware, - IAsyncCommand command) - { - ArgumentNullException.ThrowIfNull(contextAware); - ArgumentNullException.ThrowIfNull(command); - - var context = contextAware.GetContext(); - return await context.SendCommandAsync(command); - } - - /// - /// [Mediator] 发送查询的同步版本(不推荐,仅用于兼容性) - /// - /// 查询响应类型 - /// 实现 IContextAware 接口的对象 - /// 要发送的查询对象 - /// 查询结果 - /// 当 contextAware 或 query 为 null 时抛出 - public static TResponse SendQuery(this IContextAware contextAware, Mediator.IQuery query) - { - ArgumentNullException.ThrowIfNull(contextAware); - ArgumentNullException.ThrowIfNull(query); - - var context = contextAware.GetContext(); - return context.SendQuery(query); - } - - /// - /// 发送一个查询请求 - /// - /// 查询结果类型 - /// 实现 IContextAware 接口的对象 - /// 要发送的查询 - /// 查询结果 - /// 当 contextAware 或 query 为 null 时抛出 - public static TResult SendQuery(this IContextAware contextAware, Abstractions.query.IQuery query) - { - ArgumentNullException.ThrowIfNull(contextAware); - ArgumentNullException.ThrowIfNull(query); - - var context = contextAware.GetContext(); - return context.SendQuery(query); - } - - /// - /// [Mediator] 异步发送查询并返回结果 - /// - /// 查询响应类型 - /// 实现 IContextAware 接口的对象 - /// 要发送的查询对象 - /// 取消令牌,用于取消操作 - /// 包含查询结果的ValueTask - /// 当 contextAware 或 query 为 null 时抛出 - public static ValueTask SendQueryAsync(this IContextAware contextAware, - Mediator.IQuery query, CancellationToken cancellationToken = default) - { - ArgumentNullException.ThrowIfNull(contextAware); - ArgumentNullException.ThrowIfNull(query); - - var context = contextAware.GetContext(); - return context.SendQueryAsync(query, cancellationToken); - } - - /// - /// 异步发送一个查询请求 - /// - /// 查询结果类型 - /// 实现 IContextAware 接口的对象 - /// 要发送的异步查询 - /// 查询结果 - /// 当 contextAware 或 query 为 null 时抛出 - public static async Task SendQueryAsync(this IContextAware contextAware, - IAsyncQuery query) - { - ArgumentNullException.ThrowIfNull(contextAware); - ArgumentNullException.ThrowIfNull(query); - - var context = contextAware.GetContext(); - return await context.SendQueryAsync(query); - } - - // === 统一请求处理方法 === - - /// - /// 发送请求(统一处理 Command/Query) - /// - /// 响应类型 - /// 实现 IContextAware 接口的对象 - /// 要发送的请求 - /// 取消令牌 - /// 请求结果 - /// 当 contextAware 或 request 为 null 时抛出 - public static ValueTask SendRequestAsync(this IContextAware contextAware, - IRequest request, CancellationToken cancellationToken = default) - { - ArgumentNullException.ThrowIfNull(contextAware); - ArgumentNullException.ThrowIfNull(request); - - var context = contextAware.GetContext(); - return context.SendRequestAsync(request, cancellationToken); - } - - /// - /// 发送请求(同步版本,不推荐) - /// - /// 响应类型 - /// 实现 IContextAware 接口的对象 - /// 要发送的请求 - /// 请求结果 - /// 当 contextAware 或 request 为 null 时抛出 - public static TResponse SendRequest(this IContextAware contextAware, - IRequest request) - { - ArgumentNullException.ThrowIfNull(contextAware); - ArgumentNullException.ThrowIfNull(request); - - var context = contextAware.GetContext(); - return context.SendRequest(request); - } - - /// - /// 发布通知(一对多事件) - /// - /// 通知类型 - /// 实现 IContextAware 接口的对象 - /// 要发布的通知 - /// 取消令牌 - /// 异步任务 - /// 当 contextAware 或 notification 为 null 时抛出 - public static ValueTask PublishAsync(this IContextAware contextAware, - TNotification notification, CancellationToken cancellationToken = default) - where TNotification : INotification - { - ArgumentNullException.ThrowIfNull(contextAware); - ArgumentNullException.ThrowIfNull(notification); - - var context = contextAware.GetContext(); - return context.PublishAsync(notification, cancellationToken); - } - - /// - /// 创建流式请求(用于大数据集) - /// - /// 响应类型 - /// 实现 IContextAware 接口的对象 - /// 流式请求 - /// 取消令牌 - /// 异步响应流 - /// 当 contextAware 或 request 为 null 时抛出 - public static IAsyncEnumerable CreateStream(this IContextAware contextAware, - IStreamRequest request, CancellationToken cancellationToken = default) - { - ArgumentNullException.ThrowIfNull(contextAware); - ArgumentNullException.ThrowIfNull(request); - - var context = contextAware.GetContext(); - return context.CreateStream(request, cancellationToken); - } - - // === 便捷扩展方法 === - - /// - /// 发送命令(无返回值) - /// - /// 命令类型 - /// 实现 IContextAware 接口的对象 - /// 要发送的命令 - /// 取消令牌 - /// 异步任务 - /// 当 contextAware 或 command 为 null 时抛出 - public static ValueTask SendAsync(this IContextAware contextAware, TCommand command, - CancellationToken cancellationToken = default) - where TCommand : IRequest - { - ArgumentNullException.ThrowIfNull(contextAware); - ArgumentNullException.ThrowIfNull(command); - - var context = contextAware.GetContext(); - return context.SendAsync(command, cancellationToken); - } - - /// - /// 发送命令(有返回值) - /// - /// 响应类型 - /// 实现 IContextAware 接口的对象 - /// 要发送的命令 - /// 取消令牌 - /// 命令执行结果 - /// 当 contextAware 或 command 为 null 时抛出 - public static ValueTask SendAsync(this IContextAware contextAware, - IRequest command, CancellationToken cancellationToken = default) - { - ArgumentNullException.ThrowIfNull(contextAware); - ArgumentNullException.ThrowIfNull(command); - - var context = contextAware.GetContext(); - return context.SendAsync(command, cancellationToken); - } -} \ No newline at end of file diff --git a/GFramework.Core/extensions/ContextAwareMediatorExtensions.cs b/GFramework.Core/extensions/ContextAwareMediatorExtensions.cs new file mode 100644 index 0000000..05197c7 --- /dev/null +++ b/GFramework.Core/extensions/ContextAwareMediatorExtensions.cs @@ -0,0 +1,125 @@ +using GFramework.Core.Abstractions.rule; +using Mediator; + +namespace GFramework.Core.extensions; + +/// +/// 提供对 IContextAware 接口的 Mediator 统一接口扩展方法 +/// +public static class ContextAwareMediatorExtensions +{ + /// + /// 发送请求(统一处理 Command/Query) + /// + /// 响应类型 + /// 实现 IContextAware 接口的对象 + /// 要发送的请求 + /// 取消令牌 + /// 请求结果 + /// 当 contextAware 或 request 为 null 时抛出 + public static ValueTask SendRequestAsync(this IContextAware contextAware, + IRequest request, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(contextAware); + ArgumentNullException.ThrowIfNull(request); + + var context = contextAware.GetContext(); + return context.SendRequestAsync(request, cancellationToken); + } + + /// + /// 发送请求(同步版本,不推荐) + /// + /// 响应类型 + /// 实现 IContextAware 接口的对象 + /// 要发送的请求 + /// 请求结果 + /// 当 contextAware 或 request 为 null 时抛出 + public static TResponse SendRequest(this IContextAware contextAware, + IRequest request) + { + ArgumentNullException.ThrowIfNull(contextAware); + ArgumentNullException.ThrowIfNull(request); + + var context = contextAware.GetContext(); + return context.SendRequest(request); + } + + /// + /// 发布通知(一对多事件) + /// + /// 通知类型 + /// 实现 IContextAware 接口的对象 + /// 要发布的通知 + /// 取消令牌 + /// 异步任务 + /// 当 contextAware 或 notification 为 null 时抛出 + public static ValueTask PublishAsync(this IContextAware contextAware, + TNotification notification, CancellationToken cancellationToken = default) + where TNotification : INotification + { + ArgumentNullException.ThrowIfNull(contextAware); + ArgumentNullException.ThrowIfNull(notification); + + var context = contextAware.GetContext(); + return context.PublishAsync(notification, cancellationToken); + } + + /// + /// 创建流式请求(用于大数据集) + /// + /// 响应类型 + /// 实现 IContextAware 接口的对象 + /// 流式请求 + /// 取消令牌 + /// 异步响应流 + /// 当 contextAware 或 request 为 null 时抛出 + public static IAsyncEnumerable CreateStream(this IContextAware contextAware, + IStreamRequest request, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(contextAware); + ArgumentNullException.ThrowIfNull(request); + + var context = contextAware.GetContext(); + return context.CreateStream(request, cancellationToken); + } + + /// + /// 发送命令(无返回值) + /// + /// 命令类型 + /// 实现 IContextAware 接口的对象 + /// 要发送的命令 + /// 取消令牌 + /// 异步任务 + /// 当 contextAware 或 command 为 null 时抛出 + public static ValueTask SendAsync(this IContextAware contextAware, TCommand command, + CancellationToken cancellationToken = default) + where TCommand : IRequest + { + ArgumentNullException.ThrowIfNull(contextAware); + ArgumentNullException.ThrowIfNull(command); + + var context = contextAware.GetContext(); + return context.SendAsync(command, cancellationToken); + } + + /// + /// 发送命令(有返回值) + /// + /// 响应类型 + /// 实现 IContextAware 接口的对象 + /// 要发送的命令 + /// 取消令牌 + /// 命令执行结果 + /// 当 contextAware 或 command 为 null 时抛出 + public static ValueTask SendAsync(this IContextAware contextAware, + IRequest command, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(contextAware); + ArgumentNullException.ThrowIfNull(command); + + var context = contextAware.GetContext(); + return context.SendAsync(command, cancellationToken); + } +} \ No newline at end of file diff --git a/GFramework.Core/extensions/ContextAwareQueryExtensions.cs b/GFramework.Core/extensions/ContextAwareQueryExtensions.cs new file mode 100644 index 0000000..ed2d47e --- /dev/null +++ b/GFramework.Core/extensions/ContextAwareQueryExtensions.cs @@ -0,0 +1,81 @@ +using GFramework.Core.Abstractions.query; +using GFramework.Core.Abstractions.rule; + +namespace GFramework.Core.extensions; + +/// +/// 提供对 IContextAware 接口的查询执行扩展方法 +/// +public static class ContextAwareQueryExtensions +{ + /// + /// [Mediator] 发送查询的同步版本(不推荐,仅用于兼容性) + /// + /// 查询响应类型 + /// 实现 IContextAware 接口的对象 + /// 要发送的查询对象 + /// 查询结果 + /// 当 contextAware 或 query 为 null 时抛出 + public static TResponse SendQuery(this IContextAware contextAware, Mediator.IQuery query) + { + ArgumentNullException.ThrowIfNull(contextAware); + ArgumentNullException.ThrowIfNull(query); + + var context = contextAware.GetContext(); + return context.SendQuery(query); + } + + /// + /// 发送一个查询请求 + /// + /// 查询结果类型 + /// 实现 IContextAware 接口的对象 + /// 要发送的查询 + /// 查询结果 + /// 当 contextAware 或 query 为 null 时抛出 + public static TResult SendQuery(this IContextAware contextAware, Abstractions.query.IQuery query) + { + ArgumentNullException.ThrowIfNull(contextAware); + ArgumentNullException.ThrowIfNull(query); + + var context = contextAware.GetContext(); + return context.SendQuery(query); + } + + /// + /// [Mediator] 异步发送查询并返回结果 + /// + /// 查询响应类型 + /// 实现 IContextAware 接口的对象 + /// 要发送的查询对象 + /// 取消令牌,用于取消操作 + /// 包含查询结果的ValueTask + /// 当 contextAware 或 query 为 null 时抛出 + public static ValueTask SendQueryAsync(this IContextAware contextAware, + Mediator.IQuery query, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(contextAware); + ArgumentNullException.ThrowIfNull(query); + + var context = contextAware.GetContext(); + return context.SendQueryAsync(query, cancellationToken); + } + + /// + /// 异步发送一个查询请求 + /// + /// 查询结果类型 + /// 实现 IContextAware 接口的对象 + /// 要发送的异步查询 + /// 查询结果 + /// 当 contextAware 或 query 为 null 时抛出 + public static async Task SendQueryAsync(this IContextAware contextAware, + IAsyncQuery query) + { + ArgumentNullException.ThrowIfNull(contextAware); + ArgumentNullException.ThrowIfNull(query); + + var context = contextAware.GetContext(); + return await context.SendQueryAsync(query); + } +} \ No newline at end of file diff --git a/GFramework.Core/extensions/ContextAwareServiceExtensions.cs b/GFramework.Core/extensions/ContextAwareServiceExtensions.cs new file mode 100644 index 0000000..e3a6f22 --- /dev/null +++ b/GFramework.Core/extensions/ContextAwareServiceExtensions.cs @@ -0,0 +1,137 @@ +using GFramework.Core.Abstractions.model; +using GFramework.Core.Abstractions.rule; +using GFramework.Core.Abstractions.system; +using GFramework.Core.Abstractions.utility; + +namespace GFramework.Core.extensions; + +/// +/// 提供对 IContextAware 接口的服务访问扩展方法 +/// 包含单例和批量获取服务、系统、模型、工具的方法 +/// +public static class ContextAwareServiceExtensions +{ + #region 单例获取 + + /// + /// 从上下文感知对象中获取指定类型的服务 + /// + /// 要获取的服务类型 + /// 实现 IContextAware 接口的上下文感知对象 + /// 指定类型的服务实例,如果未找到则返回 null + /// 当 contextAware 参数为 null 时抛出 + public static TService? GetService(this IContextAware contextAware) where TService : class + { + ArgumentNullException.ThrowIfNull(contextAware); + var context = contextAware.GetContext(); + return context.GetService(); + } + + /// + /// 获取架构上下文中的指定系统 + /// + /// 目标系统类型 + /// 实现 IContextAware 接口的对象 + /// 指定类型的系统实例 + /// 当 contextAware 为 null 时抛出 + public static TSystem? GetSystem(this IContextAware contextAware) where TSystem : class, ISystem + { + ArgumentNullException.ThrowIfNull(contextAware); + var context = contextAware.GetContext(); + return context.GetSystem(); + } + + /// + /// 获取架构上下文中的指定模型 + /// + /// 目标模型类型 + /// 实现 IContextAware 接口的对象 + /// 指定类型的模型实例 + /// 当 contextAware 为 null 时抛出 + public static TModel? GetModel(this IContextAware contextAware) where TModel : class, IModel + { + ArgumentNullException.ThrowIfNull(contextAware); + var context = contextAware.GetContext(); + return context.GetModel(); + } + + /// + /// 获取架构上下文中的指定工具 + /// + /// 目标工具类型 + /// 实现 IContextAware 接口的对象 + /// 指定类型的工具实例 + /// 当 contextAware 为 null 时抛出 + public static TUtility? GetUtility(this IContextAware contextAware) where TUtility : class, IUtility + { + ArgumentNullException.ThrowIfNull(contextAware); + var context = contextAware.GetContext(); + return context.GetUtility(); + } + + #endregion + + #region 批量获取 + + /// + /// 从上下文感知对象中获取指定类型的所有服务 + /// + /// 要获取的服务类型 + /// 实现 IContextAware 接口的上下文感知对象 + /// 所有符合条件的服务实例列表 + /// 当 contextAware 参数为 null 时抛出 + public static IReadOnlyList GetServices(this IContextAware contextAware) + where TService : class + { + ArgumentNullException.ThrowIfNull(contextAware); + var context = contextAware.GetContext(); + return context.GetServices(); + } + + /// + /// 获取架构上下文中的所有指定系统 + /// + /// 目标系统类型 + /// 实现 IContextAware 接口的对象 + /// 所有符合条件的系统实例列表 + /// 当 contextAware 为 null 时抛出 + public static IReadOnlyList GetSystems(this IContextAware contextAware) + where TSystem : class, ISystem + { + ArgumentNullException.ThrowIfNull(contextAware); + var context = contextAware.GetContext(); + return context.GetSystems(); + } + + /// + /// 获取架构上下文中的所有指定模型 + /// + /// 目标模型类型 + /// 实现 IContextAware 接口的对象 + /// 所有符合条件的模型实例列表 + /// 当 contextAware 为 null 时抛出 + public static IReadOnlyList GetModels(this IContextAware contextAware) + where TModel : class, IModel + { + ArgumentNullException.ThrowIfNull(contextAware); + var context = contextAware.GetContext(); + return context.GetModels(); + } + + /// + /// 获取架构上下文中的所有指定工具 + /// + /// 目标工具类型 + /// 实现 IContextAware 接口的对象 + /// 所有符合条件的工具实例列表 + /// 当 contextAware 为 null 时抛出 + public static IReadOnlyList GetUtilities(this IContextAware contextAware) + where TUtility : class, IUtility + { + ArgumentNullException.ThrowIfNull(contextAware); + var context = contextAware.GetContext(); + return context.GetUtilities(); + } + + #endregion +} \ No newline at end of file