You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否将资源文件(.resx)与编译时日志源生成配合使用?

使用LoggerMessageAttribute结合资源文件的解决方案

因为[LoggerMessageAttribute]的Message参数要求是编译时常量表达式,而.resx生成的LogResource.LogText是运行时获取值的静态属性,不属于编译时常量,所以直接在属性中引用会报错。以下是两种可行的实现方式:

方法一:手动实现部分方法(兼容源生成)

源生成的LoggerExtensions是部分类,我们可以只在属性声明中指定日志级别等元数据,然后手动实现对应的部分方法,在方法内部加载资源文件的文本:

internal static partial class LoggerExtensions
{
    [LoggerMessage(Level = LogLevel.Information, EventId = 1, EventName = nameof(LogText))]
    public static partial void LogText(this ILogger logger);

    // 手动实现部分方法,加载资源文本并调用日志API
    public static partial void LogText(ILogger logger)
    {
        logger.LogInformation(LogResource.LogText);
    }
}

这种方式既保留了LoggerMessageAttribute的源生成特性(比如自动处理日志分类、事件ID),又能灵活加载资源文件的动态文本。

方法二:使用LoggerMessage.Define创建预委托

如果不需要源生成的扩展类,也可以直接用LoggerMessage.Define创建预编译的日志委托,在静态构造时加载资源文本:

internal static class LoggerExtensions
{
    private static readonly Action<ILogger> _logTextAction = LoggerMessage
        .Define(LogLevel.Information, new EventId(1, nameof(LogText)), LogResource.LogText);

    public static void LogText(this ILogger logger)
    {
        _logTextAction(logger);
    }
}

这种方式性能与源生成方案接近,适合不需要源生成额外特性的场景。

带参数的资源文本处理

如果资源文本包含占位符(比如"用户{UserName}已完成操作"),可以扩展为带参数的版本:

// 资源文件中定义:LogTextWithParam = "用户{UserName}已完成操作"
internal static class LoggerExtensions
{
    private static readonly Action<ILogger, string> _logTextWithParamAction = LoggerMessage
        .Define<string>(LogLevel.Information, new EventId(2, nameof(LogTextWithParam)), LogResource.LogTextWithParam);

    public static void LogTextWithParam(this ILogger logger, string userName)
    {
        _logTextWithParamAction(logger, userName);
    }
}

内容的提问来源于stack exchange,提问作者Abdragiz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 01:35:11