首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Microsoft.Extensions.Configuration值替换

Microsoft.Extensions.Configuration值替换
EN

Stack Overflow用户
提问于 2021-04-28 16:43:22
回答 1查看 198关注 0票数 0

动机

我有许多应用程序要为其配置日志记录,如果可能的话,我希望共享该配置。然而,每个应用程序都使用不同的应用程序路径,我正在寻找用进程名替换下面的$(ProcessName)的方法。

代码语言:javascript
复制
{
  "Serilog": {
    "WriteTo": {
      "TextFile": {
        "Name": "File",
        "Args": {
          "path": "$(ProcessName).txt",
        }
      }
    }
  }
}

要求

我知道我可以在代码中重写"Serilog:WriteTo:TextFile:Args:path",但这会将接收器名称修改为TextFile,而且无论接收器是什么,它都将始终存在。

本质上,我希望在Serilog使用它之前在Microsoft.Extensions.Configuration上执行转换。热重装需要工作,所以一次转换不起作用。

尝试

  1. 创建了我自己的配置源/提供程序(我知道这不是serilog特定的),但是我无法让它工作--
  2. ,查看ReloadToken,看看我是否可以只编写一个处理程序,它每次更改配置时都会重写配置,但是ReloadToken是非常不符合人类工程学的。

配置源/提供者包装器的重要部分:

代码语言:javascript
复制
public class SubstitutionConfigurationSource : IConfigurationSource
{
    private readonly IConfigurationSource _inner;
    private readonly IEnumerable<KeyValuePair<string, string>> _substitutions;
...
    public IConfigurationProvider Build(IConfigurationBuilder builder) => new SubstitutionConfigurationProvider(_inner.Build(builder), _substitutions);
}

public class SubstitutionConfigurationProvider: IConfigurationProvider
{
    private readonly IConfigurationProvider _inner;
    private readonly IEnumerable<KeyValuePair<string, string>> _substitutions;
...
    public bool TryGet(string key, out string value)
    {
        if (!_inner.TryGet(key, out value)) return false;

        value = Substitute(value);
        return true;
    }

    private string Substitute(string value)
    {
        foreach (var (key, val) in _substitutions)
        {
            value = value.Replace(key, val);
        }
        return value;
    }
}
代码语言:javascript
复制
IConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
configurationBuilder.Add(new SubstitutionConfigurationSource(
        // The JsonConfigurationSource can't find the file unfortunately. Stopped persuing this approach because of it.
        new JsonConfigurationSource
        {
            FileProvider = configurationBuilder.GetFileProvider(),
            Path = "serilog.json"
            Optional = false,
            ReloadOnChange = true,
        },
        new KeyValuePair<string, string>[]
        {
            new ("$(ProcessName)", processName),
        }
        )
    )
    .AddJsonFile("appsettings.json", true, true);

问题

我无法想象我自己是唯一一个寻找这个的人。我该怎么做?切换到另一种编程语言?

EN

回答 1

Stack Overflow用户

发布于 2022-01-09 11:06:16

您可以执行我所做的工作,并使用我在代码中手动设置的环境变量:

代码语言:javascript
复制
// Set environmental variables that can be used inside appSettings.json
Environment.SetEnvironmentVariable("CUROUTDIR", OPGPathManager.CurrentOutputDirectory);

var processName = Process.GetCurrentProcess().ProcessName;
Environment.SetEnvironmentVariable("PROCESSNAME", PathHelpers.ReplaceInvalidChars(processName, '_'));

只需在加载配置之前运行该代码即可。然后你可以做这样的事情:

代码语言:javascript
复制
"path": "%CUROUTDIR%\\..\\Logs\\%PROCESSNAME%\\%PROCESSNAME% .txt",

编辑:奇怪的是,我找不到任何关于appsettings.json能够扩展env的文档。像这样的变数。这可能是serilog的一个特性,或者只是一般的应用程序设置--但这对于我的serilog文件接收器来说是可行的。

还有一些替代库可以处理这类事情,比如:

https://github.com/molinch/ConfigurationSubstitutor

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67304445

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档