mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-22 10:34:30 +08:00
refactor(architecture): 重构日志系统和配置属性结构
- 将日志工厂配置改为日志属性配置,使用LoggerProperties替代ILoggerFactory - 引入ArchitectureProperties替代ArchitectureOptions,统一架构配置属性 - 修改日志记录器创建方式,使用LoggerFactoryResolver.Provider统一管理 - 重构控制台日志工厂提供程序接口,移除minLevel参数 - 更新架构配置接口和上下文接口中的日志相关属性 - 移除Godot日志生成器相关的源代码生成器和特性 - 更新源代码生成器中的日志创建逻辑,使用新的日志工厂解析器
This commit is contained in:
parent
435c3398fc
commit
f620dea073
@ -1,4 +1,4 @@
|
|||||||
using GFramework.Core.Abstractions.logging;
|
using GFramework.Core.Abstractions.properties;
|
||||||
|
|
||||||
namespace GFramework.Core.Abstractions.architecture;
|
namespace GFramework.Core.Abstractions.architecture;
|
||||||
|
|
||||||
@ -8,12 +8,12 @@ namespace GFramework.Core.Abstractions.architecture;
|
|||||||
public interface IArchitectureConfiguration
|
public interface IArchitectureConfiguration
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取或设置日志工厂,用于创建日志记录器实例
|
/// 获取或设置日志选项,包含日志相关的配置参数
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ILoggerFactory LoggerFactory { get; set; }
|
LoggerProperties LoggerProperties { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取或设置架构选项,包含架构相关的配置参数
|
/// 获取或设置架构选项,包含架构相关的配置参数
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ArchitectureOptions Options { get; set; }
|
ArchitectureProperties ArchitectureProperties { get; set; }
|
||||||
}
|
}
|
||||||
@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using GFramework.Core.Abstractions.command;
|
using GFramework.Core.Abstractions.command;
|
||||||
using GFramework.Core.Abstractions.events;
|
using GFramework.Core.Abstractions.events;
|
||||||
using GFramework.Core.Abstractions.logging;
|
|
||||||
using GFramework.Core.Abstractions.model;
|
using GFramework.Core.Abstractions.model;
|
||||||
using GFramework.Core.Abstractions.query;
|
using GFramework.Core.Abstractions.query;
|
||||||
using GFramework.Core.Abstractions.system;
|
using GFramework.Core.Abstractions.system;
|
||||||
@ -14,11 +13,6 @@ namespace GFramework.Core.Abstractions.architecture;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IArchitectureContext
|
public interface IArchitectureContext
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// 获取日志工厂
|
|
||||||
/// </summary>
|
|
||||||
ILoggerFactory LoggerFactory { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取指定类型的系统实例
|
/// 获取指定类型的系统实例
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -5,11 +5,15 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface ILoggerFactoryProvider
|
public interface ILoggerFactoryProvider
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置日志记录器的最小日志级别,低于此级别的日志将被忽略
|
||||||
|
/// </summary>
|
||||||
|
public LogLevel MinLevel { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 创建一个日志记录器实例
|
/// 创建一个日志记录器实例
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">日志记录器的名称,用于标识特定的日志源</param>
|
/// <param name="name">日志记录器的名称,用于标识特定的日志源</param>
|
||||||
/// <param name="minLevel">日志记录器的最小日志级别,低于此级别的日志消息将被忽略</param>
|
|
||||||
/// <returns>配置了指定名称和最小日志级别的ILogger实例</returns>
|
/// <returns>配置了指定名称和最小日志级别的ILogger实例</returns>
|
||||||
ILogger CreateLogger(string name, LogLevel minLevel);
|
ILogger CreateLogger(string name);
|
||||||
}
|
}
|
||||||
@ -1,20 +1,17 @@
|
|||||||
namespace GFramework.Core.Abstractions.architecture;
|
namespace GFramework.Core.Abstractions.properties;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 架构选项配置类,用于定义架构行为的相关配置选项
|
/// 架构选项配置类,用于定义架构行为的相关配置选项
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class ArchitectureOptions(
|
public sealed class ArchitectureProperties
|
||||||
bool strictPhaseValidation = true,
|
|
||||||
bool allowLateRegistration = false
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 允许延迟注册开关,当设置为true时允许在初始化完成后进行组件注册
|
/// 允许延迟注册开关,当设置为true时允许在初始化完成后进行组件注册
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool AllowLateRegistration { get; } = allowLateRegistration;
|
public bool AllowLateRegistration { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 严格阶段验证开关,当设置为true时启用严格的阶段验证机制
|
/// 严格阶段验证开关,当设置为true时启用严格的阶段验证机制
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool StrictPhaseValidation { get; } = strictPhaseValidation;
|
public bool StrictPhaseValidation { get; set; }
|
||||||
}
|
}
|
||||||
15
GFramework.Core.Abstractions/properties/LoggerProperties.cs
Normal file
15
GFramework.Core.Abstractions/properties/LoggerProperties.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using GFramework.Core.Abstractions.logging;
|
||||||
|
|
||||||
|
namespace GFramework.Core.Abstractions.properties;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 日志配置选项类,用于配置日志系统的相关参数
|
||||||
|
/// </summary>
|
||||||
|
public sealed class LoggerProperties
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置日志工厂提供程序
|
||||||
|
/// 可为空,用于提供自定义的日志工厂实现
|
||||||
|
/// </summary>
|
||||||
|
public ILoggerFactoryProvider LoggerFactoryProvider { get; set; } = null!;
|
||||||
|
}
|
||||||
@ -7,6 +7,7 @@ using GFramework.Core.Abstractions.model;
|
|||||||
using GFramework.Core.Abstractions.system;
|
using GFramework.Core.Abstractions.system;
|
||||||
using GFramework.Core.Abstractions.utility;
|
using GFramework.Core.Abstractions.utility;
|
||||||
using GFramework.Core.events;
|
using GFramework.Core.events;
|
||||||
|
using GFramework.Core.logging;
|
||||||
|
|
||||||
namespace GFramework.Core.architecture;
|
namespace GFramework.Core.architecture;
|
||||||
|
|
||||||
@ -70,7 +71,8 @@ public abstract class Architecture(
|
|||||||
/// <param name="module">要安装的模块</param>
|
/// <param name="module">要安装的模块</param>
|
||||||
public void InstallModule(IArchitectureModule module)
|
public void InstallModule(IArchitectureModule module)
|
||||||
{
|
{
|
||||||
var logger = Configuration.LoggerFactory.GetLogger(nameof(Architecture));
|
var logger =
|
||||||
|
LoggerFactoryResolver.Provider.CreateLogger(nameof(GetType));
|
||||||
logger.Debug($"Installing module: {module.GetType().Name}");
|
logger.Debug($"Installing module: {module.GetType().Name}");
|
||||||
RegisterLifecycleHook(module);
|
RegisterLifecycleHook(module);
|
||||||
Container.RegisterPlurality(module);
|
Container.RegisterPlurality(module);
|
||||||
@ -132,28 +134,27 @@ public abstract class Architecture(
|
|||||||
/// <exception cref="InvalidOperationException">当阶段转换不被允许时抛出异常</exception>
|
/// <exception cref="InvalidOperationException">当阶段转换不被允许时抛出异常</exception>
|
||||||
private void EnterPhase(ArchitecturePhase next)
|
private void EnterPhase(ArchitecturePhase next)
|
||||||
{
|
{
|
||||||
var logger = Configuration.LoggerFactory.GetLogger(nameof(Architecture));
|
if (Configuration.ArchitectureProperties.StrictPhaseValidation &&
|
||||||
if (Configuration.Options.StrictPhaseValidation &&
|
|
||||||
(!ArchitectureConstants.PhaseTransitions.TryGetValue(CurrentPhase, out var allowed) ||
|
(!ArchitectureConstants.PhaseTransitions.TryGetValue(CurrentPhase, out var allowed) ||
|
||||||
!allowed.Contains(next)))
|
!allowed.Contains(next)))
|
||||||
{
|
{
|
||||||
// 验证阶段转换是否合法
|
// 验证阶段转换是否合法
|
||||||
var errorMsg = $"Invalid phase transition: {CurrentPhase} -> {next}";
|
var errorMsg = $"Invalid phase transition: {CurrentPhase} -> {next}";
|
||||||
logger.Fatal(errorMsg);
|
_logger.Fatal(errorMsg);
|
||||||
throw new InvalidOperationException(errorMsg);
|
throw new InvalidOperationException(errorMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
var previousPhase = CurrentPhase;
|
var previousPhase = CurrentPhase;
|
||||||
CurrentPhase = next;
|
CurrentPhase = next;
|
||||||
|
|
||||||
if (previousPhase != next) logger.Info($"Architecture phase changed: {previousPhase} -> {next}");
|
if (previousPhase != next) _logger.Info($"Architecture phase changed: {previousPhase} -> {next}");
|
||||||
|
|
||||||
NotifyPhase(next);
|
NotifyPhase(next);
|
||||||
|
|
||||||
// 通知所有架构阶段感知对象阶段变更
|
// 通知所有架构阶段感知对象阶段变更
|
||||||
foreach (var obj in Container.GetAll<IArchitecturePhaseAware>())
|
foreach (var obj in Container.GetAll<IArchitecturePhaseAware>())
|
||||||
{
|
{
|
||||||
logger.Debug($"Notifying phase-aware object {obj.GetType().Name} of phase change to {next}");
|
_logger.Debug($"Notifying phase-aware object {obj.GetType().Name} of phase change to {next}");
|
||||||
obj.OnArchitecturePhase(next);
|
obj.OnArchitecturePhase(next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -174,7 +175,7 @@ public abstract class Architecture(
|
|||||||
/// <param name="hook">生命周期钩子实例</param>
|
/// <param name="hook">生命周期钩子实例</param>
|
||||||
public void RegisterLifecycleHook(IArchitectureLifecycle hook)
|
public void RegisterLifecycleHook(IArchitectureLifecycle hook)
|
||||||
{
|
{
|
||||||
if (CurrentPhase >= ArchitecturePhase.Ready && !Configuration.Options.AllowLateRegistration)
|
if (CurrentPhase >= ArchitecturePhase.Ready && !Configuration.ArchitectureProperties.AllowLateRegistration)
|
||||||
throw new InvalidOperationException(
|
throw new InvalidOperationException(
|
||||||
"Cannot register lifecycle hook after architecture is Ready");
|
"Cannot register lifecycle hook after architecture is Ready");
|
||||||
_lifecycleHooks.Add(hook);
|
_lifecycleHooks.Add(hook);
|
||||||
@ -195,25 +196,23 @@ public abstract class Architecture(
|
|||||||
/// </remarks>
|
/// </remarks>
|
||||||
public virtual void Destroy()
|
public virtual void Destroy()
|
||||||
{
|
{
|
||||||
var logger = Configuration.LoggerFactory.GetLogger(nameof(Architecture));
|
|
||||||
|
|
||||||
// 检查当前阶段,如果已经处于销毁或已销毁状态则直接返回
|
// 检查当前阶段,如果已经处于销毁或已销毁状态则直接返回
|
||||||
if (CurrentPhase >= ArchitecturePhase.Destroying)
|
if (CurrentPhase >= ArchitecturePhase.Destroying)
|
||||||
{
|
{
|
||||||
logger.Warn("Architecture destroy called but already in destroying/destroyed state");
|
_logger.Warn("Architecture destroy called but already in destroying/destroyed state");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 进入销毁阶段并发送销毁开始事件
|
// 进入销毁阶段并发送销毁开始事件
|
||||||
logger.Info("Starting architecture destruction");
|
_logger.Info("Starting architecture destruction");
|
||||||
EnterPhase(ArchitecturePhase.Destroying);
|
EnterPhase(ArchitecturePhase.Destroying);
|
||||||
TypeEventSystem.Send(new ArchitectureEvents.ArchitectureDestroyingEvent());
|
TypeEventSystem.Send(new ArchitectureEvents.ArchitectureDestroyingEvent());
|
||||||
|
|
||||||
// 销毁所有系统组件并清空系统列表
|
// 销毁所有系统组件并清空系统列表
|
||||||
logger.Info($"Destroying {_allSystems.Count} systems");
|
_logger.Info($"Destroying {_allSystems.Count} systems");
|
||||||
foreach (var system in _allSystems)
|
foreach (var system in _allSystems)
|
||||||
{
|
{
|
||||||
logger.Debug($"Destroying system: {system.GetType().Name}");
|
_logger.Debug($"Destroying system: {system.GetType().Name}");
|
||||||
system.Destroy();
|
system.Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,7 +221,7 @@ public abstract class Architecture(
|
|||||||
// 进入已销毁阶段并发送销毁完成事件
|
// 进入已销毁阶段并发送销毁完成事件
|
||||||
EnterPhase(ArchitecturePhase.Destroyed);
|
EnterPhase(ArchitecturePhase.Destroyed);
|
||||||
TypeEventSystem.Send(new ArchitectureEvents.ArchitectureDestroyedEvent());
|
TypeEventSystem.Send(new ArchitectureEvents.ArchitectureDestroyedEvent());
|
||||||
logger.Info("Architecture destruction completed");
|
_logger.Info("Architecture destruction completed");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -231,8 +230,10 @@ public abstract class Architecture(
|
|||||||
|
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
_logger = Configuration.LoggerFactory.GetLogger(GetType().Name);
|
// 设置日志工厂提供程序,用于创建日志记录器
|
||||||
_context ??= new ArchitectureContext(Container, TypeEventSystem, Configuration.LoggerFactory);
|
LoggerFactoryResolver.Provider = Configuration.LoggerProperties.LoggerFactoryProvider;
|
||||||
|
_logger = LoggerFactoryResolver.Provider.CreateLogger(GetType().Name);
|
||||||
|
_context ??= new ArchitectureContext(Container, TypeEventSystem, Configuration.LoggerProperties);
|
||||||
GameContext.Bind(GetType(), _context);
|
GameContext.Bind(GetType(), _context);
|
||||||
// 创建架构运行时实例
|
// 创建架构运行时实例
|
||||||
Runtime = new ArchitectureRuntime(_context);
|
Runtime = new ArchitectureRuntime(_context);
|
||||||
@ -284,8 +285,11 @@ public abstract class Architecture(
|
|||||||
|
|
||||||
public async Task InitializeAsync()
|
public async Task InitializeAsync()
|
||||||
{
|
{
|
||||||
_logger = Configuration.LoggerFactory.GetLogger(GetType().Name);
|
// 设置日志工厂提供程序,用于创建日志记录器
|
||||||
_context ??= new ArchitectureContext(Container, TypeEventSystem, Configuration.LoggerFactory);
|
LoggerFactoryResolver.Provider = Configuration.LoggerProperties.LoggerFactoryProvider;
|
||||||
|
// 创建日志记录器
|
||||||
|
_logger = LoggerFactoryResolver.Provider.CreateLogger(GetType().Name);
|
||||||
|
_context ??= new ArchitectureContext(Container, TypeEventSystem, Configuration.LoggerProperties);
|
||||||
GameContext.Bind(GetType(), _context);
|
GameContext.Bind(GetType(), _context);
|
||||||
// 创建架构运行时实例
|
// 创建架构运行时实例
|
||||||
Runtime = new ArchitectureRuntime(_context);
|
Runtime = new ArchitectureRuntime(_context);
|
||||||
@ -347,7 +351,7 @@ public abstract class Architecture(
|
|||||||
/// <param name="system">要注册的系统实例</param>
|
/// <param name="system">要注册的系统实例</param>
|
||||||
public void RegisterSystem<TSystem>(TSystem system) where TSystem : ISystem
|
public void RegisterSystem<TSystem>(TSystem system) where TSystem : ISystem
|
||||||
{
|
{
|
||||||
if (CurrentPhase >= ArchitecturePhase.Ready && !Configuration.Options.AllowLateRegistration)
|
if (CurrentPhase >= ArchitecturePhase.Ready && !Configuration.ArchitectureProperties.AllowLateRegistration)
|
||||||
{
|
{
|
||||||
const string errorMsg = "Cannot register system after Architecture is Ready";
|
const string errorMsg = "Cannot register system after Architecture is Ready";
|
||||||
_logger.Error(errorMsg);
|
_logger.Error(errorMsg);
|
||||||
@ -379,7 +383,7 @@ public abstract class Architecture(
|
|||||||
/// <param name="model">要注册的模型实例</param>
|
/// <param name="model">要注册的模型实例</param>
|
||||||
public void RegisterModel<TModel>(TModel model) where TModel : IModel
|
public void RegisterModel<TModel>(TModel model) where TModel : IModel
|
||||||
{
|
{
|
||||||
if (CurrentPhase >= ArchitecturePhase.Ready && !Configuration.Options.AllowLateRegistration)
|
if (CurrentPhase >= ArchitecturePhase.Ready && !Configuration.ArchitectureProperties.AllowLateRegistration)
|
||||||
{
|
{
|
||||||
var errorMsg = "Cannot register model after Architecture is Ready";
|
var errorMsg = "Cannot register model after Architecture is Ready";
|
||||||
_logger.Error(errorMsg);
|
_logger.Error(errorMsg);
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using GFramework.Core.Abstractions.architecture;
|
using GFramework.Core.Abstractions.architecture;
|
||||||
using GFramework.Core.Abstractions.logging;
|
using GFramework.Core.Abstractions.logging;
|
||||||
|
using GFramework.Core.Abstractions.properties;
|
||||||
using GFramework.Core.logging;
|
using GFramework.Core.logging;
|
||||||
|
|
||||||
namespace GFramework.Core.architecture;
|
namespace GFramework.Core.architecture;
|
||||||
@ -8,23 +9,27 @@ namespace GFramework.Core.architecture;
|
|||||||
/// 默认架构配置类,实现IArchitectureConfiguration接口
|
/// 默认架构配置类,实现IArchitectureConfiguration接口
|
||||||
/// 提供日志工厂、日志级别和架构选项的默认配置
|
/// 提供日志工厂、日志级别和架构选项的默认配置
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ArchitectureConfiguration : IArchitectureConfiguration
|
public sealed class ArchitectureConfiguration : IArchitectureConfiguration
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取或设置日志级别
|
/// 获取或设置日志选项
|
||||||
/// 默认设置为Info级别
|
/// 默认配置为Info级别日志,使用控制台日志工厂提供程序
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public LogLevel LogLevel { get; set; } = LogLevel.Info;
|
public LoggerProperties LoggerProperties { get; set; } = new()
|
||||||
|
{
|
||||||
/// <summary>
|
LoggerFactoryProvider = new ConsoleLoggerFactoryProvider()
|
||||||
/// 获取或设置日志工厂实例
|
{
|
||||||
/// 默认使用控制台日志工厂
|
MinLevel = LogLevel.Info
|
||||||
/// </summary>
|
}
|
||||||
public ILoggerFactory LoggerFactory { get; set; } = new ConsoleLoggerFactory();
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取或设置架构选项
|
/// 获取或设置架构选项
|
||||||
/// 默认创建新的ArchitectureOptions实例
|
/// 默认创建新的ArchitectureOptions实例
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ArchitectureOptions Options { get; set; } = new();
|
public ArchitectureProperties ArchitectureProperties { get; set; } = new()
|
||||||
|
{
|
||||||
|
AllowLateRegistration = false,
|
||||||
|
StrictPhaseValidation = true
|
||||||
|
};
|
||||||
}
|
}
|
||||||
@ -2,12 +2,11 @@
|
|||||||
using GFramework.Core.Abstractions.command;
|
using GFramework.Core.Abstractions.command;
|
||||||
using GFramework.Core.Abstractions.events;
|
using GFramework.Core.Abstractions.events;
|
||||||
using GFramework.Core.Abstractions.ioc;
|
using GFramework.Core.Abstractions.ioc;
|
||||||
using GFramework.Core.Abstractions.logging;
|
|
||||||
using GFramework.Core.Abstractions.model;
|
using GFramework.Core.Abstractions.model;
|
||||||
|
using GFramework.Core.Abstractions.properties;
|
||||||
using GFramework.Core.Abstractions.query;
|
using GFramework.Core.Abstractions.query;
|
||||||
using GFramework.Core.Abstractions.system;
|
using GFramework.Core.Abstractions.system;
|
||||||
using GFramework.Core.Abstractions.utility;
|
using GFramework.Core.Abstractions.utility;
|
||||||
using GFramework.Core.logging;
|
|
||||||
|
|
||||||
namespace GFramework.Core.architecture;
|
namespace GFramework.Core.architecture;
|
||||||
|
|
||||||
@ -17,7 +16,7 @@ namespace GFramework.Core.architecture;
|
|||||||
public class ArchitectureContext(
|
public class ArchitectureContext(
|
||||||
IIocContainer container,
|
IIocContainer container,
|
||||||
ITypeEventSystem typeEventSystem,
|
ITypeEventSystem typeEventSystem,
|
||||||
ILoggerFactory? loggerFactory)
|
LoggerProperties loggerProperties)
|
||||||
: IArchitectureContext
|
: IArchitectureContext
|
||||||
{
|
{
|
||||||
private readonly IIocContainer _container = container ?? throw new ArgumentNullException(nameof(container));
|
private readonly IIocContainer _container = container ?? throw new ArgumentNullException(nameof(container));
|
||||||
@ -27,8 +26,6 @@ public class ArchitectureContext(
|
|||||||
|
|
||||||
internal IArchitectureRuntime Runtime { get; set; } = null!;
|
internal IArchitectureRuntime Runtime { get; set; } = null!;
|
||||||
|
|
||||||
public ILoggerFactory LoggerFactory { get; } = loggerFactory ?? new NoopLoggerFactory();
|
|
||||||
|
|
||||||
#region Query Execution
|
#region Query Execution
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
using GFramework.Core.Abstractions.ioc;
|
using GFramework.Core.Abstractions.ioc;
|
||||||
using GFramework.Core.Abstractions.logging;
|
using GFramework.Core.Abstractions.logging;
|
||||||
using GFramework.Core.Abstractions.system;
|
using GFramework.Core.Abstractions.system;
|
||||||
|
using GFramework.Core.logging;
|
||||||
using GFramework.Core.rule;
|
using GFramework.Core.rule;
|
||||||
|
|
||||||
namespace GFramework.Core.ioc;
|
namespace GFramework.Core.ioc;
|
||||||
@ -54,7 +55,8 @@ public class IocContainer : ContextAwareBase, IIocContainer
|
|||||||
|
|
||||||
protected override void OnContextReady()
|
protected override void OnContextReady()
|
||||||
{
|
{
|
||||||
_logger = Context.LoggerFactory.GetLogger(nameof(IocContainer));
|
_logger =
|
||||||
|
LoggerFactoryResolver.Provider.CreateLogger(nameof(GetType));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -7,12 +7,16 @@ namespace GFramework.Core.logging;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class ConsoleLoggerFactoryProvider : ILoggerFactoryProvider
|
public sealed class ConsoleLoggerFactoryProvider : ILoggerFactoryProvider
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置日志记录器的最小日志级别,低于此级别的日志将被忽略
|
||||||
|
/// </summary>
|
||||||
|
public LogLevel MinLevel { get; set; } = LogLevel.Info;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 创建一个日志记录器实例
|
/// 创建一个日志记录器实例
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">日志记录器的名称,用于标识特定的日志源</param>
|
/// <param name="name">日志记录器的名称,用于标识特定的日志源</param>
|
||||||
/// <param name="minLevel">日志记录器的最小日志级别,低于此级别的日志消息将被忽略</param>
|
|
||||||
/// <returns>配置了指定名称和最小日志级别的ILogger实例</returns>
|
/// <returns>配置了指定名称和最小日志级别的ILogger实例</returns>
|
||||||
public ILogger CreateLogger(string name, LogLevel minLevel)
|
public ILogger CreateLogger(string name)
|
||||||
=> new ConsoleLoggerFactory().GetLogger(name, minLevel);
|
=> new ConsoleLoggerFactory().GetLogger(name, MinLevel);
|
||||||
}
|
}
|
||||||
@ -15,4 +15,12 @@ public static class LoggerFactoryResolver
|
|||||||
/// </value>
|
/// </value>
|
||||||
public static ILoggerFactoryProvider Provider { get; set; }
|
public static ILoggerFactoryProvider Provider { get; set; }
|
||||||
= new ConsoleLoggerFactoryProvider();
|
= new ConsoleLoggerFactoryProvider();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置日志记录的最小级别
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// 日志级别枚举值,默认为Info级别
|
||||||
|
/// </value>
|
||||||
|
public static LogLevel MinLevel { get; set; } = LogLevel.Info;
|
||||||
}
|
}
|
||||||
@ -11,7 +11,7 @@ public abstract class ContextAwareBase : IContextAware
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取当前实例的架构上下文
|
/// 获取当前实例的架构上下文
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected IArchitectureContext Context { get; private set; } = null!;
|
protected IArchitectureContext Context { get; set; } = null!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设置架构上下文的实现方法,由框架调用
|
/// 设置架构上下文的实现方法,由框架调用
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
using GFramework.Core.Abstractions.enums;
|
using GFramework.Core.Abstractions.enums;
|
||||||
using GFramework.Core.Abstractions.logging;
|
using GFramework.Core.Abstractions.logging;
|
||||||
using GFramework.Core.Abstractions.system;
|
using GFramework.Core.Abstractions.system;
|
||||||
|
using GFramework.Core.logging;
|
||||||
using GFramework.Core.rule;
|
using GFramework.Core.rule;
|
||||||
|
|
||||||
namespace GFramework.Core.system;
|
namespace GFramework.Core.system;
|
||||||
@ -18,7 +19,7 @@ public abstract class AbstractSystem : ContextAwareBase, ISystem
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
void ISystem.Init()
|
void ISystem.Init()
|
||||||
{
|
{
|
||||||
_logger = Context.LoggerFactory.GetLogger(nameof(AbstractSystem));
|
_logger = LoggerFactoryResolver.Provider.CreateLogger(nameof(GetType));
|
||||||
_logger.Debug($"Initializing system: {GetType().Name}");
|
_logger.Debug($"Initializing system: {GetType().Name}");
|
||||||
|
|
||||||
OnInit();
|
OnInit();
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using GFramework.Core.Abstractions.logging;
|
using GFramework.Core.Abstractions.logging;
|
||||||
using GFramework.Core.Abstractions.utility;
|
using GFramework.Core.Abstractions.utility;
|
||||||
|
using GFramework.Core.logging;
|
||||||
using GFramework.Core.rule;
|
using GFramework.Core.rule;
|
||||||
|
|
||||||
namespace GFramework.Core.utility;
|
namespace GFramework.Core.utility;
|
||||||
@ -18,7 +19,7 @@ public abstract class AbstractContextUtility : ContextAwareBase, IContextUtility
|
|||||||
void IContextUtility.Init()
|
void IContextUtility.Init()
|
||||||
{
|
{
|
||||||
// 获取上下文中的日志记录器
|
// 获取上下文中的日志记录器
|
||||||
Logger = Context.LoggerFactory.GetLogger(nameof(AbstractContextUtility));
|
Logger = LoggerFactoryResolver.Provider.CreateLogger(nameof(GetType));
|
||||||
Logger.Debug($"Initializing Context Utility: {GetType().Name}");
|
Logger.Debug($"Initializing Context Utility: {GetType().Name}");
|
||||||
|
|
||||||
// 执行子类实现的初始化逻辑
|
// 执行子类实现的初始化逻辑
|
||||||
|
|||||||
@ -15,4 +15,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Using Include="GFramework.Godot.SourceGenerators.Abstractions"/>
|
<Using Include="GFramework.Godot.SourceGenerators.Abstractions"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="logging\"/>
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@ -1,38 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace GFramework.Godot.SourceGenerators.Abstractions.logging;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Godot日志特性,用于在类上标记以自动生成日志字段
|
|
||||||
/// </summary>
|
|
||||||
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
|
|
||||||
public sealed class GodotLogAttribute : Attribute
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 初始化 GodotLogAttribute 类的新实例
|
|
||||||
/// </summary>
|
|
||||||
public GodotLogAttribute()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 初始化 GodotLogAttribute 类的新实例
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="name">日志分类名</param>
|
|
||||||
public GodotLogAttribute(string? name)
|
|
||||||
{
|
|
||||||
Name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>日志分类名(默认使用类名)</summary>
|
|
||||||
public string? Name { get; set; }
|
|
||||||
|
|
||||||
/// <summary>生成字段名</summary>
|
|
||||||
public string FieldName { get; set; } = "Logger";
|
|
||||||
|
|
||||||
/// <summary>是否生成 static 字段</summary>
|
|
||||||
public bool IsStatic { get; set; } = true;
|
|
||||||
|
|
||||||
/// <summary>访问修饰符</summary>
|
|
||||||
public string AccessModifier { get; set; } = "private";
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
; Shipped analyzer releases
|
|
||||||
; https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md
|
|
||||||
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
; Unshipped analyzer release
|
|
||||||
; https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md
|
|
||||||
|
|
||||||
### New Rules
|
|
||||||
|
|
||||||
Rule ID | Category | Severity | Notes
|
|
||||||
----------------------|--------------------------|----------|------------------------
|
|
||||||
GF_Godot_Logging_001 | GFramework.Godot.Logging | Warning | GodotLoggerDiagnostics
|
|
||||||
@ -59,4 +59,12 @@
|
|||||||
<!-- 包含targets文件 -->
|
<!-- 包含targets文件 -->
|
||||||
<None Include="GeWuYou.$(AssemblyName).targets" Pack="true" PackagePath="build" Visible="false"/>
|
<None Include="GeWuYou.$(AssemblyName).targets" Pack="true" PackagePath="build" Visible="false"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="diagnostics\"/>
|
||||||
|
<Folder Include="logging\"/>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<AdditionalFiles Remove="AnalyzerReleases.Shipped.md"/>
|
||||||
|
<AdditionalFiles Remove="AnalyzerReleases.Unshipped.md"/>
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@ -1,25 +0,0 @@
|
|||||||
using Microsoft.CodeAnalysis;
|
|
||||||
|
|
||||||
namespace GFramework.Godot.SourceGenerators.diagnostics;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 提供诊断描述符的静态类,用于GFramework日志生成器的编译时检查
|
|
||||||
/// </summary>
|
|
||||||
internal static class GodotLoggerDiagnostics
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 诊断描述符:标识GodotLogAttribute无法在指定类上生成Logger
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// ID: GFW_LOG001
|
|
||||||
/// 严重性: Warning
|
|
||||||
/// 分类: GFramework.Godot.Logging
|
|
||||||
/// </remarks>
|
|
||||||
public static readonly DiagnosticDescriptor LogAttributeInvalid = new(
|
|
||||||
"GF_Godot_Logging_001",
|
|
||||||
"GodotLogAttribute cannot generate Logger",
|
|
||||||
"GodotLogAttribute on class '{0}' is ineffective: {1}",
|
|
||||||
"GFramework.Godot.Logging",
|
|
||||||
DiagnosticSeverity.Warning,
|
|
||||||
true);
|
|
||||||
}
|
|
||||||
@ -1,96 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using GFramework.Godot.SourceGenerators.Abstractions.logging;
|
|
||||||
using GFramework.SourceGenerators.Common.constants;
|
|
||||||
using GFramework.SourceGenerators.Common.generator;
|
|
||||||
using Microsoft.CodeAnalysis;
|
|
||||||
|
|
||||||
namespace GFramework.Godot.SourceGenerators.logging;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 日志生成器,用于为标记了GodotLogAttribute的类自动生成日志字段
|
|
||||||
/// </summary>
|
|
||||||
[Generator]
|
|
||||||
public sealed class GodotLoggerGenerator : TypeAttributeClassGeneratorBase
|
|
||||||
{
|
|
||||||
protected override Type AttributeType => typeof(GodotLogAttribute);
|
|
||||||
|
|
||||||
|
|
||||||
protected override string AttributeShortNameWithoutSuffix => "GodotLog";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 生成源代码
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="context">源生产上下文</param>
|
|
||||||
/// <param name="compilation">编译对象</param>
|
|
||||||
/// <param name="symbol">命名类型符号</param>
|
|
||||||
/// <param name="attr">属性数据</param>
|
|
||||||
/// <returns>生成的源代码字符串</returns>
|
|
||||||
protected override string Generate(
|
|
||||||
SourceProductionContext context,
|
|
||||||
Compilation compilation,
|
|
||||||
INamedTypeSymbol symbol,
|
|
||||||
AttributeData attr)
|
|
||||||
{
|
|
||||||
var ns = symbol.ContainingNamespace.IsGlobalNamespace
|
|
||||||
? null
|
|
||||||
: symbol.ContainingNamespace.ToDisplayString();
|
|
||||||
var className = symbol.Name;
|
|
||||||
|
|
||||||
// 解析构造函数参数
|
|
||||||
var name = className;
|
|
||||||
if (attr.ConstructorArguments.Length > 0 && attr.ConstructorArguments[0].Value is string s &&
|
|
||||||
!string.IsNullOrWhiteSpace(s))
|
|
||||||
{
|
|
||||||
name = s;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 解析命名参数
|
|
||||||
var fieldName = GetNamedArg(attr, "FieldName")?.ToString() ?? "_log";
|
|
||||||
var access = GetNamedArg(attr, "AccessModifier")?.ToString() ?? "private";
|
|
||||||
var isStatic = GetNamedArg(attr, "IsStatic") is not bool b || b;
|
|
||||||
var staticKeyword = isStatic ? "static " : "";
|
|
||||||
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
sb.AppendLine("// <auto-generated />");
|
|
||||||
sb.AppendLine($"using {PathContests.CoreAbstractionsNamespace}.logging;");
|
|
||||||
sb.AppendLine($"using {PathContests.GodotNamespace}.logging;");
|
|
||||||
sb.AppendLine();
|
|
||||||
|
|
||||||
if (ns is not null)
|
|
||||||
{
|
|
||||||
sb.AppendLine($"namespace {ns}");
|
|
||||||
sb.AppendLine("{");
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.AppendLine($" public partial class {className}");
|
|
||||||
sb.AppendLine(" {");
|
|
||||||
sb.AppendLine(" /// <summary>Auto-generated logger</summary>");
|
|
||||||
sb.AppendLine(
|
|
||||||
$" {access} {staticKeyword}readonly ILogger {fieldName} = new GodotLoggerFactory().GetLogger(\"{name}\");");
|
|
||||||
sb.AppendLine(" }");
|
|
||||||
|
|
||||||
if (ns is not null)
|
|
||||||
sb.AppendLine("}");
|
|
||||||
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取生成文件的提示名称
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="symbol">类型符号</param>
|
|
||||||
/// <returns>生成文件的提示名称</returns>
|
|
||||||
protected override string GetHintName(INamedTypeSymbol symbol)
|
|
||||||
=> $"{symbol.Name}.Logger.g.cs";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取属性的命名参数值
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="attr">属性数据</param>
|
|
||||||
/// <param name="name">参数名称</param>
|
|
||||||
/// <returns>参数值</returns>
|
|
||||||
private static object? GetNamedArg(AttributeData attr, string name)
|
|
||||||
=> attr.NamedArguments.FirstOrDefault(kv => kv.Key == name).Value.Value;
|
|
||||||
}
|
|
||||||
@ -8,11 +8,14 @@ namespace GFramework.Godot.logging;
|
|||||||
public sealed class GodotLoggerFactoryProvider : ILoggerFactoryProvider
|
public sealed class GodotLoggerFactoryProvider : ILoggerFactoryProvider
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 创建指定名称和最小日志级别的日志记录器
|
/// 获取或设置最小日志级别
|
||||||
|
/// </summary>
|
||||||
|
public LogLevel MinLevel { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建指定名称的日志记录器实例
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">日志记录器的名称</param>
|
/// <param name="name">日志记录器的名称</param>
|
||||||
/// <param name="minLevel">日志记录器的最小日志级别</param>
|
/// <returns>返回配置了最小日志级别的Godot日志记录器实例</returns>
|
||||||
/// <returns>返回配置好的Godot日志记录器实例</returns>
|
public ILogger CreateLogger(string name) => new GodotLoggerFactory().GetLogger(name, MinLevel);
|
||||||
public ILogger CreateLogger(string name, LogLevel minLevel)
|
|
||||||
=> new GodotLoggerFactory().GetLogger(name, minLevel);
|
|
||||||
}
|
}
|
||||||
@ -1,6 +1,5 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
using System;
|
using System;
|
||||||
using GFramework.Core.Abstractions.logging;
|
|
||||||
|
|
||||||
namespace GFramework.SourceGenerators.Abstractions.logging;
|
namespace GFramework.SourceGenerators.Abstractions.logging;
|
||||||
|
|
||||||
@ -38,7 +37,4 @@ public sealed class LogAttribute : Attribute
|
|||||||
|
|
||||||
/// <summary>访问修饰符</summary>
|
/// <summary>访问修饰符</summary>
|
||||||
public string AccessModifier { get; set; } = "private";
|
public string AccessModifier { get; set; } = "private";
|
||||||
|
|
||||||
/// <summary>最小日志级别</summary>
|
|
||||||
public LogLevel MinLevel { get; set; } = LogLevel.Info;
|
|
||||||
}
|
}
|
||||||
@ -92,7 +92,7 @@ public sealed class LoggerGenerator : TypeAttributeClassGeneratorBase
|
|||||||
sb.AppendLine("{");
|
sb.AppendLine("{");
|
||||||
sb.AppendLine(" /// <summary>Auto-generated logger</summary>");
|
sb.AppendLine(" /// <summary>Auto-generated logger</summary>");
|
||||||
sb.AppendLine(
|
sb.AppendLine(
|
||||||
$" {access} {staticKeyword}readonly ILogger {fieldName} = new ConsoleLoggerFactory().GetLogger(\"{name}\");");
|
$" {access} {staticKeyword}readonly ILogger {fieldName} = LoggerFactoryResolver.Provider.CreateLogger(\"{name}\");");
|
||||||
sb.AppendLine("}");
|
sb.AppendLine("}");
|
||||||
|
|
||||||
return sb.ToString().TrimEnd();
|
return sb.ToString().TrimEnd();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user