保留记录 words/characters

Logging reserved words/characters

我有一个 *.resx 字符串,如下所示:

Failed to deserialize an object of type '{0}' from the following string:{1}{2}

此字符串用于记录此类错误,目前,记录语句如下所示:

_logger.LogError(Resources.FailedToDeserialize, typeof(MyType).Name, Environment.NewLine, invalidJsonString);

如您所见 - 我每次都需要通过 Environment.NewLine 才能正确显示任何 OS 的日志。

我很好奇是否有任何保留的字符串插值words/characters来插入这样的值?

例如,我的字符串可能如下所示:

Failed to deserialize an object of type '{0}' from the following string:{NewLine}{2}

我的日志记录语句会更简单一些:

_logger.LogError(Resources.FailedToDeserialize, typeof(MyType).Name, invalidJsonString);

您可以做的一件事是在应用程序启动时进行某种形式的预处理,方法是读取资源文件,将您选择的关键字(即 {NewLine} 替换为 Environment.NewLine,然后将缓存的字符串用于整个应用程序生命周期。

您可以制作字段 readonly 并使用一些反射魔法来设置值,但是这个示例应该让您了解如何解决当前的问题。

public static class LoggingMessageTemplates
{
    //Reference your resource here e.g Resource.FailedToDeserialize
    public static string FailedToDeserialize = "Resource.Something {NewLine} Something Else";
    
    public static void FormatMessages() 
    {
        var stringFields = typeof(LoggingMessageTemplates)
            .GetFields()
            .Where(x => x.FieldType == typeof(string));
        
        foreach(var field in stringFields) 
        {
            if (field.GetValue(null) is not string fieldValue)
            {
                throw new InvalidCastException($"Failed to cast field {field.Name} to string.");
            }
            
            field.SetValue(null, fieldValue.Replace("{NewLine}", Environment.NewLine));
        }
    }
}

//On application startup, format the resources to use the Environment.NewLine char of the current system.
LoggingMessageTemplates.FormatMessages();

//When logging, reference the LoggingMessageTemplates class rather than the direct resource.
Console.WriteLine(LoggingMessageTemplates.FailedToDeserialize);

//i.e
_logger.LogError(LoggingMessageTemplates.FailedToDeserialize, typeof(MyType).Name, invalidJsonString);