如何在Blazor模板的Nlog.Config中动态获取项目解决方案名称?
解决方案:动态替换NLog配置中的项目名称
问题背景
你需要将Blazor模板中NLog配置文件nlog.config里fileName路径的固定值KitchenSink,替换为当前项目/解决方案的名称,此前尝试的$(MSBuildProjectName)未被解析,直接作为字符串输出。
方法1:MSBuild构建时替换配置内容
通过修改项目文件,让MSBuild在构建过程中自动替换配置文件中的占位符:
- 修改NLog配置:将
KitchenSink替换为占位符__PROJECT_NAME__
<nlog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <targets> <target name="logfile" fileName="C:/webcorp/NLogs/__PROJECT_NAME__/${shortdate}/${logger}.txt" xsi:type="File"> <layout xsi:type="JsonLayout"> <attribute name="time" layout="${longdate}" /> <attribute name="logger" layout="${logger}" /> <attribute name="level" layout="${level}" /> <attribute name="callsite" layout="${callsite}" /> <attribute name="message" layout="${message}" /> </layout> </target> </targets> <rules> <logger name="*" minlevel="Trace" writeTo="logfile" /> </rules> </nlog>
- 修改项目.csproj文件:添加以下配置,实现构建时的文本替换
<ItemGroup> <None Include="nlog.config"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> </ItemGroup> <Target Name="ReplaceNlogProjectName" BeforeTargets="Build"> <FileUpdate Files="$(OutputPath)nlog.config" Regex="__PROJECT_NAME__" ReplacementText="$(MSBuildProjectName)" /> </Target>
构建完成后,输出目录中的nlog.config会自动将占位符替换为实际项目名称。
方法2:代码中动态配置NLog(推荐)
放弃静态配置的依赖,在项目启动时动态设置NLog的目标路径:
- 简化NLog配置:移除
fileName的固定路径部分
<nlog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <targets> <target name="logfile" xsi:type="File"> <layout xsi:type="JsonLayout"> <attribute name="time" layout="${longdate}" /> <attribute name="logger" layout="${logger}" /> <attribute name="level" layout="${level}" /> <attribute name="callsite" layout="${callsite}" /> <attribute name="message" layout="${message}" /> </layout> </target> </targets> <rules> <logger name="*" minlevel="Trace" writeTo="logfile" /> </rules> </nlog>
- 在Program.cs中动态配置:
var builder = WebApplication.CreateBuilder(args); // 获取当前项目名称(程序集名称) var projectName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name; // 加载NLog配置并动态修改路径 var nlogConfig = NLog.LogManager.LoadConfiguration("nlog.config").Configuration; var fileTarget = nlogConfig.FindTargetByName<NLog.Targets.FileTarget>("logfile"); if (fileTarget != null) { // 注意NLog布局变量需用双花括号转义 fileTarget.FileName = $"C:/webcorp/NLogs/{projectName}/${{shortdate}}/${{logger}}.txt"; } // 替换日志提供器 builder.Logging.ClearProviders(); builder.Logging.AddNLog(nlogConfig); // 其他Blazor启动配置... var app = builder.Build(); // ...
方法3:自定义NLog布局渲染器
创建自定义渲染器直接返回项目名称,在配置中直接调用:
- 创建自定义渲染器类:
using NLog.LayoutRenderers; using System.Reflection; [LayoutRenderer("project-name")] public class ProjectNameLayoutRenderer : LayoutRenderer { protected override void Append(StringBuilder builder, NLog.LogEventInfo logEvent) { var projectName = Assembly.GetExecutingAssembly().GetName().Name; builder.Append(projectName); } }
- 注册并使用渲染器:
在Program.cs启动代码中注册:
NLog.Config.ConfigurationItemFactory.Default.LayoutRenderers.RegisterDefinition("project-name", typeof(ProjectNameLayoutRenderer)); NLog.LogManager.LoadConfiguration("nlog.config");
修改nlog.config的fileName:
<target name="logfile" fileName="C:/webcorp/NLogs/${project-name}/${shortdate}/${logger}.txt" xsi:type="File">
额外注意
原配置中存在两处无效规则,建议删除:
<logger name="*" minlevel="Info" writeTo="jsonFile" />:未定义jsonFile目标<logger name="*" minlevel="Info" readFrom="jsonFile" />:NLog规则无readFrom属性
内容的提问来源于stack exchange,提问作者ExecChef
相关产品推荐
相关产品推荐

