diff --git a/GFramework.Core.Abstractions/architecture/IArchitectureContext.cs b/GFramework.Core.Abstractions/architecture/IArchitectureContext.cs
index aa2451c..d02c877 100644
--- a/GFramework.Core.Abstractions/architecture/IArchitectureContext.cs
+++ b/GFramework.Core.Abstractions/architecture/IArchitectureContext.cs
@@ -1,5 +1,6 @@
using System;
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;
@@ -83,4 +84,10 @@ public interface IArchitectureContext
/// 事件类型
/// 要取消注册的事件回调方法
void UnRegisterEvent(Action onEvent);
+
+ ///
+ /// 获取环境对象
+ ///
+ /// 环境对象实例
+ IEnvironment GetEnvironment();
}
\ No newline at end of file
diff --git a/GFramework.Core.Abstractions/environment/IEnvironment.cs b/GFramework.Core.Abstractions/environment/IEnvironment.cs
new file mode 100644
index 0000000..9c75bfb
--- /dev/null
+++ b/GFramework.Core.Abstractions/environment/IEnvironment.cs
@@ -0,0 +1,50 @@
+namespace GFramework.Core.Abstractions.environment;
+
+///
+/// 定义环境接口,提供应用程序运行环境的相关信息
+///
+public interface IEnvironment
+{
+ ///
+ /// 获取环境名称
+ ///
+ public string Name { get; }
+
+
+ ///
+ /// 根据键值获取指定类型的环境配置值
+ ///
+ /// 要获取的值的类型,必须为引用类型
+ /// 用于查找配置值的键
+ /// 与指定键关联的配置值,如果未找到则返回null
+ T? Get(string key) where T : class;
+
+ ///
+ /// 尝试获取环境值(显式判断)
+ ///
+ /// 要获取的值的类型,必须为引用类型
+ /// 用于查找配置值的键
+ /// 输出参数,如果找到配置值则返回该值,否则返回默认值
+ /// 如果找到指定键的配置值则返回true,否则返回false
+ bool TryGet(string key, out T value) where T : class;
+
+ ///
+ /// 获取必须存在的环境值(强依赖)
+ ///
+ /// 要获取的值的类型,必须为引用类型
+ /// 用于查找配置值的键
+ /// 与指定键关联的配置值,如果未找到则抛出异常
+ T GetRequired(string key) where T : class;
+
+ ///
+ /// 注册键值对到环境值字典中
+ ///
+ /// 要注册的键
+ /// 要注册的值
+ void Register(string key, object value);
+
+ ///
+ /// 初始化环境值字典
+ ///
+ void Initialize();
+}
\ No newline at end of file
diff --git a/GFramework.Core/architecture/Architecture.cs b/GFramework.Core/architecture/Architecture.cs
index 4c58c44..dda7ad9 100644
--- a/GFramework.Core/architecture/Architecture.cs
+++ b/GFramework.Core/architecture/Architecture.cs
@@ -1,6 +1,7 @@
using GFramework.Core.Abstractions.architecture;
using GFramework.Core.Abstractions.command;
using GFramework.Core.Abstractions.enums;
+using GFramework.Core.Abstractions.environment;
using GFramework.Core.Abstractions.events;
using GFramework.Core.Abstractions.ioc;
using GFramework.Core.Abstractions.logging;
@@ -8,6 +9,7 @@ using GFramework.Core.Abstractions.model;
using GFramework.Core.Abstractions.query;
using GFramework.Core.Abstractions.system;
using GFramework.Core.Abstractions.utility;
+using GFramework.Core.environment;
using GFramework.Core.events;
using GFramework.Core.logging;
@@ -20,19 +22,29 @@ namespace GFramework.Core.architecture;
///
public abstract class Architecture(
IArchitectureConfiguration? configuration = null,
+ IEnvironment? environment = null,
IArchitectureServices? services = null,
IArchitectureContext? context = null
)
: IArchitecture
{
///
- /// 获取架构配置对象
+ /// 获取架构配置对象
///
///
- /// 返回一个IArchitectureConfiguration接口的实例,默认为DefaultArchitectureConfiguration类型
+ /// 返回一个IArchitectureConfiguration接口的实例,默认为DefaultArchitectureConfiguration类型
///
private IArchitectureConfiguration Configuration { get; } = configuration ?? new ArchitectureConfiguration();
+ ///
+ /// 获取环境配置对象
+ ///
+ ///
+ /// 返回一个IEnvironment接口的实例,默认为DefaultEnvironment类型
+ ///
+ private IEnvironment Environment { get; } = environment ?? new DefaultEnvironment();
+
+
///
/// 获取架构服务对象
///
@@ -304,9 +316,9 @@ public abstract class Architecture(
LoggerFactoryResolver.Provider = Configuration.LoggerProperties.LoggerFactoryProvider;
// 创建日志记录器实例
_logger = LoggerFactoryResolver.Provider.CreateLogger(GetType().Name);
-
+ Environment.Initialize();
// 初始化架构上下文(如果尚未初始化)
- _context ??= new ArchitectureContext(Container, TypeEventSystem, CommandBus, QueryBus);
+ _context ??= new ArchitectureContext(Container, TypeEventSystem, CommandBus, QueryBus, Environment);
// 将当前架构类型与上下文绑定到游戏上下文
GameContext.Bind(GetType(), _context);
diff --git a/GFramework.Core/architecture/ArchitectureContext.cs b/GFramework.Core/architecture/ArchitectureContext.cs
index 606a0a3..7e01224 100644
--- a/GFramework.Core/architecture/ArchitectureContext.cs
+++ b/GFramework.Core/architecture/ArchitectureContext.cs
@@ -1,5 +1,6 @@
using GFramework.Core.Abstractions.architecture;
using GFramework.Core.Abstractions.command;
+using GFramework.Core.Abstractions.environment;
using GFramework.Core.Abstractions.events;
using GFramework.Core.Abstractions.ioc;
using GFramework.Core.Abstractions.model;
@@ -16,11 +17,14 @@ public class ArchitectureContext(
IIocContainer container,
ITypeEventSystem typeEventSystem,
ICommandBus commandBus,
- IQueryBus queryBus)
+ IQueryBus queryBus,
+ IEnvironment environment)
: IArchitectureContext
{
private readonly ICommandBus _commandBus = commandBus ?? throw new ArgumentNullException(nameof(commandBus));
private readonly IIocContainer _container = container ?? throw new ArgumentNullException(nameof(container));
+
+ private readonly IEnvironment _environment = environment ?? throw new ArgumentNullException(nameof(environment));
private readonly IQueryBus _queryBus = queryBus ?? throw new ArgumentNullException(nameof(queryBus));
private readonly ITypeEventSystem _typeEventSystem =
@@ -145,5 +149,14 @@ public class ArchitectureContext(
_typeEventSystem.UnRegister(onEvent);
}
+ ///
+ /// 获取当前环境对象
+ ///
+ /// 环境对象实例
+ public IEnvironment GetEnvironment()
+ {
+ return _environment;
+ }
+
#endregion
}
\ No newline at end of file
diff --git a/GFramework.Core/environment/DefaultEnvironment.cs b/GFramework.Core/environment/DefaultEnvironment.cs
new file mode 100644
index 0000000..39644c7
--- /dev/null
+++ b/GFramework.Core/environment/DefaultEnvironment.cs
@@ -0,0 +1,19 @@
+namespace GFramework.Core.environment;
+
+///
+/// 默认环境实现类,继承自EnvironmentBase
+///
+public class DefaultEnvironment : EnvironmentBase
+{
+ ///
+ /// 获取环境名称
+ ///
+ public override string Name { get; } = "Default";
+
+ ///
+ /// 初始化环境
+ ///
+ public override void Initialize()
+ {
+ }
+}
\ No newline at end of file
diff --git a/GFramework.Core/environment/EnvironmentBase.cs b/GFramework.Core/environment/EnvironmentBase.cs
new file mode 100644
index 0000000..292033d
--- /dev/null
+++ b/GFramework.Core/environment/EnvironmentBase.cs
@@ -0,0 +1,83 @@
+using GFramework.Core.Abstractions.environment;
+using GFramework.Core.rule;
+
+namespace GFramework.Core.environment;
+
+///
+/// 环境基础抽象类,实现了IEnvironment接口,提供环境值的存储和获取功能
+///
+public abstract class EnvironmentBase : ContextAwareBase, IEnvironment
+{
+ ///
+ /// 存储环境值的字典,键为字符串,值为对象类型
+ ///
+ protected readonly Dictionary Values = new();
+
+ ///
+ /// 获取环境名称的抽象属性
+ ///
+ public abstract string Name { get; }
+
+ ///
+ /// 根据键获取指定类型的值
+ ///
+ /// 要获取的值的类型,必须为引用类型
+ /// 用于查找值的键
+ /// 如果找到则返回对应类型的值,否则返回null
+ public virtual T? Get(string key) where T : class
+ {
+ return TryGet(key, out var value) ? value : null;
+ }
+
+ ///
+ /// 尝试根据键获取指定类型的值
+ ///
+ /// 要获取的值的类型,必须为引用类型
+ /// 用于查找值的键
+ /// 输出参数,如果成功则包含找到的值,否则为null
+ /// 如果找到指定键且类型匹配则返回true,否则返回false
+ public virtual bool TryGet(string key, out T value) where T : class
+ {
+ if (Values.TryGetValue(key, out var obj) && obj is T typed)
+ {
+ value = typed;
+ return true;
+ }
+
+ value = null!;
+ return false;
+ }
+
+ ///
+ /// 根据键获取必需的指定类型值,如果找不到则抛出异常
+ ///
+ /// 要获取的值的类型,必须为引用类型
+ /// 用于查找值的键
+ /// 找到的对应类型的值
+ /// 当指定键的值不存在时抛出
+ public virtual T GetRequired(string key) where T : class
+ {
+ if (TryGet(key, out var value))
+ return value;
+
+ throw new InvalidOperationException(
+ $"Environment [{Name}] missing required value: key='{key}', type='{typeof(T).Name}'");
+ }
+
+ void IEnvironment.Register(string key, object value)
+ {
+ Register(key, value);
+ }
+
+ public abstract void Initialize();
+
+ ///
+ /// 注册键值对到环境值字典中
+ ///
+ /// 要注册的键
+ /// 要注册的值
+ protected void Register(string key, object value)
+ {
+ Values[key] = value;
+ }
+}
\ No newline at end of file
diff --git a/GFramework.Core/extensions/ContextAwareExtensions.cs b/GFramework.Core/extensions/ContextAwareExtensions.cs
index 3a5af4b..0b79530 100644
--- a/GFramework.Core/extensions/ContextAwareExtensions.cs
+++ b/GFramework.Core/extensions/ContextAwareExtensions.cs
@@ -1,4 +1,5 @@
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;
@@ -22,7 +23,7 @@ public static class ContextAwareExtensions
/// 当 contextAware 为 null 时抛出
public static TSystem? GetSystem(this IContextAware contextAware) where TSystem : class, ISystem
{
- if (contextAware == null) throw new ArgumentNullException(nameof(contextAware));
+ ArgumentNullException.ThrowIfNull(contextAware);
var context = contextAware.GetContext();
return context.GetSystem();
}
@@ -36,7 +37,7 @@ public static class ContextAwareExtensions
/// 当 contextAware 为 null 时抛出
public static TModel? GetModel(this IContextAware contextAware) where TModel : class, IModel
{
- if (contextAware == null) throw new ArgumentNullException(nameof(contextAware));
+ ArgumentNullException.ThrowIfNull(contextAware);
var context = contextAware.GetContext();
return context.GetModel();
}
@@ -50,7 +51,7 @@ public static class ContextAwareExtensions
/// 当 contextAware 为 null 时抛出
public static TUtility? GetUtility(this IContextAware contextAware) where TUtility : class, IUtility
{
- if (contextAware == null) throw new ArgumentNullException(nameof(contextAware));
+ ArgumentNullException.ThrowIfNull(contextAware);
var context = contextAware.GetContext();
return context.GetUtility();
}
@@ -65,8 +66,8 @@ public static class ContextAwareExtensions
/// 当 contextAware 或 query 为 null 时抛出
public static TResult SendQuery(this IContextAware contextAware, IQuery query)
{
- if (contextAware == null) throw new ArgumentNullException(nameof(contextAware));
- if (query == null) throw new ArgumentNullException(nameof(query));
+ ArgumentNullException.ThrowIfNull(contextAware);
+ ArgumentNullException.ThrowIfNull(query);
var context = contextAware.GetContext();
return context.SendQuery(query);
@@ -80,8 +81,8 @@ public static class ContextAwareExtensions
/// 当 contextAware 或 command 为 null 时抛出
public static void SendCommand(this IContextAware contextAware, ICommand command)
{
- if (contextAware == null) throw new ArgumentNullException(nameof(contextAware));
- if (command == null) throw new ArgumentNullException(nameof(command));
+ ArgumentNullException.ThrowIfNull(contextAware);
+ ArgumentNullException.ThrowIfNull(command);
var context = contextAware.GetContext();
context.SendCommand(command);
@@ -97,8 +98,8 @@ public static class ContextAwareExtensions
/// 当 contextAware 或 command 为 null 时抛出
public static TResult SendCommand(this IContextAware contextAware, ICommand command)
{
- if (contextAware == null) throw new ArgumentNullException(nameof(contextAware));
- if (command == null) throw new ArgumentNullException(nameof(command));
+ ArgumentNullException.ThrowIfNull(contextAware);
+ ArgumentNullException.ThrowIfNull(command);
var context = contextAware.GetContext();
return context.SendCommand(command);
@@ -112,7 +113,7 @@ public static class ContextAwareExtensions
/// 当 contextAware 为 null 时抛出
public static void SendEvent(this IContextAware contextAware) where TEvent : new()
{
- if (contextAware == null) throw new ArgumentNullException(nameof(contextAware));
+ ArgumentNullException.ThrowIfNull(contextAware);
var context = contextAware.GetContext();
context.SendEvent();
}
@@ -126,8 +127,8 @@ public static class ContextAwareExtensions
/// 当 contextAware 或 e 为 null 时抛出
public static void SendEvent(this IContextAware contextAware, TEvent e) where TEvent : class
{
- if (contextAware == null) throw new ArgumentNullException(nameof(contextAware));
- if (e == null) throw new ArgumentNullException(nameof(e));
+ ArgumentNullException.ThrowIfNull(contextAware);
+ ArgumentNullException.ThrowIfNull(e);
var context = contextAware.GetContext();
context.SendEvent(e);
@@ -142,8 +143,8 @@ public static class ContextAwareExtensions
/// 事件注销接口
public static IUnRegister RegisterEvent(this IContextAware contextAware, Action handler)
{
- if (contextAware == null) throw new ArgumentNullException(nameof(contextAware));
- if (handler == null) throw new ArgumentNullException(nameof(handler));
+ ArgumentNullException.ThrowIfNull(contextAware);
+ ArgumentNullException.ThrowIfNull(handler);
var context = contextAware.GetContext();
return context.RegisterEvent(handler);
@@ -157,10 +158,39 @@ public static class ContextAwareExtensions
/// 之前绑定的事件处理器
public static void UnRegisterEvent(this IContextAware contextAware, Action onEvent)
{
- if (contextAware == null) throw new ArgumentNullException(nameof(contextAware));
- if (onEvent == null) throw new ArgumentNullException(nameof(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();
+ }
}
\ No newline at end of file
diff --git a/GFramework.Core/logging/NoopLogger.cs b/GFramework.Core/logging/NoopLogger.cs
deleted file mode 100644
index b598d7a..0000000
--- a/GFramework.Core/logging/NoopLogger.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using GFramework.Core.Abstractions.logging;
-
-namespace GFramework.Core.logging;
-
-///
-/// 空操作日志记录器实现,不执行任何实际的日志记录操作
-///
-/// 日志记录器名称,默认为null
-/// 最小日志级别,默认为Info
-internal sealed class NoopLogger(
- string? name = null,
- LogLevel minLevel = LogLevel.Info) : AbstractLogger(name ?? RootLoggerName, minLevel)
-{
- ///
- /// 重写写入方法,空操作实现,不执行任何实际的日志记录操作
- ///
- /// 日志级别
- /// 日志消息
- /// 异常信息
- protected override void Write(LogLevel level, string message, Exception? exception)
- {
- }
-}
\ No newline at end of file
diff --git a/GFramework.Core/logging/NoopLoggerFactory.cs b/GFramework.Core/logging/NoopLoggerFactory.cs
deleted file mode 100644
index 1d493e6..0000000
--- a/GFramework.Core/logging/NoopLoggerFactory.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using GFramework.Core.Abstractions.logging;
-
-namespace GFramework.Core.logging;
-
-///
-/// 无操作日志工厂实现,用于提供空的日志记录功能
-///
-public class NoopLoggerFactory : ILoggerFactory
-{
- ///
- /// 获取指定名称的无操作日志记录器
- ///
- /// 日志记录器的名称
- /// 日志记录器的最小日志级别
- /// 返回一个NoopLogger实例,该实例不执行任何实际的日志记录操作
- public ILogger GetLogger(string name, LogLevel minLevel = LogLevel.Info)
- {
- return new NoopLogger();
- }
-}
\ No newline at end of file
diff --git a/GFramework.Godot/architecture/AbstractArchitecture.cs b/GFramework.Godot/architecture/AbstractArchitecture.cs
index 621575e..fb43ecb 100644
--- a/GFramework.Godot/architecture/AbstractArchitecture.cs
+++ b/GFramework.Godot/architecture/AbstractArchitecture.cs
@@ -1,4 +1,8 @@
-using GFramework.Core.Abstractions.architecture;
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using GFramework.Core.Abstractions.architecture;
+using GFramework.Core.Abstractions.environment;
using GFramework.Core.architecture;
using GFramework.Core.constants;
using GFramework.Godot.extensions;
@@ -12,9 +16,10 @@ namespace GFramework.Godot.architecture;
///
public abstract class AbstractArchitecture(
IArchitectureConfiguration? configuration = null,
+ IEnvironment? environment = null,
IArchitectureServices? services = null,
IArchitectureContext? context = null
-) : Architecture(configuration, services, context)
+) : Architecture(configuration, environment, services, context)
{
///
/// 存储所有已安装的Godot架构扩展组件列表
diff --git a/GFramework.Godot/architecture/ArchitectureAnchor.cs b/GFramework.Godot/architecture/ArchitectureAnchor.cs
index 2884184..2dbe047 100644
--- a/GFramework.Godot/architecture/ArchitectureAnchor.cs
+++ b/GFramework.Godot/architecture/ArchitectureAnchor.cs
@@ -1,4 +1,5 @@
-using Godot;
+using System;
+using Godot;
namespace GFramework.Godot.architecture;