将复杂结构与 AddEnvironmentVariables 一起使用
Using complex structures with AddEnvironmentVariables
问题
如何在使用 ConfigurationBuilder
的 AddEnvironmentVariables
方法设置配置时处理复杂的结构,例如数组。
即调用什么环境变量来表示以下结构?
{
"MyApp": {
"SendAlertsTo": [
{"Name": "Joe Blogger", "Email": "JoeBlogger@example.com"},
{"Name": "Jane Doer", "Email": "JaneDoer@example.com"}
]
}
}
带上下文的详细版本
我们正在编写将在容器中托管的应用程序。最初我们继续使用 AppSettings.json
文件来保存设置,在启动时通过 entrypoint.sh
shell 脚本从环境变量填充此文件的内容。
后来我们意识到我们可以使用ConfigurationBuilder
的AddEnvironmentVariables
方法直接从环境变量中提取值,从而避免维护entrypoint.sh
脚本的开销作为每次添加新设置时更新的另一个地方。
这适用于应用程序设置文件,例如:
{
"MyApp": {
"SmtpServer": "smtp.example.com",
"FromAddress": "JoeyBlogger@example.com"
},
"Logging": {
"LogLevel": "Default"
}
}
.. 因为这简单地转化为:
export MyApp:SmtpServer=smtp.example.com
export MyApp:FromAddress=JoeyBlogger@example.com
export Logging:LogLevel=Default
但是,我最近看到一个开发人员的应用程序设置文件,用于一些新的监控,如下所示(注意;这不是我们托管环境中使用的实际设置;它只是触发此问题的示例).在这种情况下,使用上述方法效果不佳,因为名称为 Serilog:WriteTo:Name
的两个不同设置以及以 Serilog:WriteTo:Args:*
开头的任何条目都与哪个条目相关的歧义。
{
"Serilog"
"WriteTo": [
{
"Name": "Async",
"Args": {
"configure": [
{
"Name": "File",
"Args": {
"path": ".\log.txt",
"rollingInterval": "Day",
"retainedFileCountLimit": 7,
"buffered": true
}
}
]
}
},
{
"Name": "Async",
"Args": {
"configure": [
{
"Name": "Console"
}
]
}
}
]
}
}
我猜我们会通过某种索引来处理这个问题;但我无法在文档中找到任何关于此的内容。
export Serilog:WriteTo[0]:Name=Async
export Serilog:WriteTo[0]:Args:configure[0]:Name=File
export Serilog:WriteTo[0]:Args:configure[0]:Args:path=.\log.txt
export Serilog:WriteTo[0]:Args:configure[0]:Args:rollingInterval=Day
export Serilog:WriteTo[0]:Args:configure[0]:Args:retainedFileCountLimit=7
export Serilog:WriteTo[0]:Args:configure[0]:Args:buffered=true
export Serilog:WriteTo[1]:Name=Async
export Serilog:WriteTo[1]:Args:configure[0]:Name=Console
但是,运行 一个快速的 PoC 表明上述方法不起作用。如何做到这一点?
我在这里找到了解决方案:MS Extensions Configuration Deep Dive。
答案是使用索引,但索引号被当作命名元素处理;即
{
"MyApp": {
"SendAlertsTo": [
{"Name": "Joe Blogger", "Email": "JoeBlogger@example.com"},
{"Name": "Jane Doer", "Email": "JaneDoer@example.com"}
]
}
}
变为:
export MyApp:SendAlertsTo:0:Name=Joe Blogger
export MyApp:SendAlertsTo:0:Email=JoeBlogger@example.com
export MyApp:SendAlertsTo:1:Name=Jane Doer
export MyApp:SendAlertsTo:1:Email=JaneDoer@example.com
此外,对于 Linux 托管还有一点我不知道/与数组问题无关.. :
分隔符应该是 __
,所以上面变成:
export MyApp__SendAlertsTo__0__Name=Joe Blogger
export MyApp__SendAlertsTo__0__Email=JoeBlogger@example.com
export MyApp__SendAlertsTo__1__Name=Jane Doer
export MyApp__SendAlertsTo__1__Email=JaneDoer@example.com
问题
如何在使用 ConfigurationBuilder
的 AddEnvironmentVariables
方法设置配置时处理复杂的结构,例如数组。
即调用什么环境变量来表示以下结构?
{
"MyApp": {
"SendAlertsTo": [
{"Name": "Joe Blogger", "Email": "JoeBlogger@example.com"},
{"Name": "Jane Doer", "Email": "JaneDoer@example.com"}
]
}
}
带上下文的详细版本
我们正在编写将在容器中托管的应用程序。最初我们继续使用 AppSettings.json
文件来保存设置,在启动时通过 entrypoint.sh
shell 脚本从环境变量填充此文件的内容。
后来我们意识到我们可以使用ConfigurationBuilder
的AddEnvironmentVariables
方法直接从环境变量中提取值,从而避免维护entrypoint.sh
脚本的开销作为每次添加新设置时更新的另一个地方。
这适用于应用程序设置文件,例如:
{
"MyApp": {
"SmtpServer": "smtp.example.com",
"FromAddress": "JoeyBlogger@example.com"
},
"Logging": {
"LogLevel": "Default"
}
}
.. 因为这简单地转化为:
export MyApp:SmtpServer=smtp.example.com
export MyApp:FromAddress=JoeyBlogger@example.com
export Logging:LogLevel=Default
但是,我最近看到一个开发人员的应用程序设置文件,用于一些新的监控,如下所示(注意;这不是我们托管环境中使用的实际设置;它只是触发此问题的示例).在这种情况下,使用上述方法效果不佳,因为名称为 Serilog:WriteTo:Name
的两个不同设置以及以 Serilog:WriteTo:Args:*
开头的任何条目都与哪个条目相关的歧义。
{
"Serilog"
"WriteTo": [
{
"Name": "Async",
"Args": {
"configure": [
{
"Name": "File",
"Args": {
"path": ".\log.txt",
"rollingInterval": "Day",
"retainedFileCountLimit": 7,
"buffered": true
}
}
]
}
},
{
"Name": "Async",
"Args": {
"configure": [
{
"Name": "Console"
}
]
}
}
]
}
}
我猜我们会通过某种索引来处理这个问题;但我无法在文档中找到任何关于此的内容。
export Serilog:WriteTo[0]:Name=Async
export Serilog:WriteTo[0]:Args:configure[0]:Name=File
export Serilog:WriteTo[0]:Args:configure[0]:Args:path=.\log.txt
export Serilog:WriteTo[0]:Args:configure[0]:Args:rollingInterval=Day
export Serilog:WriteTo[0]:Args:configure[0]:Args:retainedFileCountLimit=7
export Serilog:WriteTo[0]:Args:configure[0]:Args:buffered=true
export Serilog:WriteTo[1]:Name=Async
export Serilog:WriteTo[1]:Args:configure[0]:Name=Console
但是,运行 一个快速的 PoC 表明上述方法不起作用。如何做到这一点?
我在这里找到了解决方案:MS Extensions Configuration Deep Dive。
答案是使用索引,但索引号被当作命名元素处理;即
{
"MyApp": {
"SendAlertsTo": [
{"Name": "Joe Blogger", "Email": "JoeBlogger@example.com"},
{"Name": "Jane Doer", "Email": "JaneDoer@example.com"}
]
}
}
变为:
export MyApp:SendAlertsTo:0:Name=Joe Blogger
export MyApp:SendAlertsTo:0:Email=JoeBlogger@example.com
export MyApp:SendAlertsTo:1:Name=Jane Doer
export MyApp:SendAlertsTo:1:Email=JaneDoer@example.com
此外,对于 Linux 托管还有一点我不知道/与数组问题无关.. :
分隔符应该是 __
,所以上面变成:
export MyApp__SendAlertsTo__0__Name=Joe Blogger
export MyApp__SendAlertsTo__0__Email=JoeBlogger@example.com
export MyApp__SendAlertsTo__1__Name=Jane Doer
export MyApp__SendAlertsTo__1__Email=JaneDoer@example.com