DotNetConfig.CommandLine 1.2.0
dotnet add package DotNetConfig.CommandLine --version 1.2.0
NuGet\Install-Package DotNetConfig.CommandLine -Version 1.2.0
<PackageReference Include="DotNetConfig.CommandLine" Version="1.2.0" />
paket add DotNetConfig.CommandLine --version 1.2.0
#r "nuget: DotNetConfig.CommandLine, 1.2.0"
// Install DotNetConfig.CommandLine as a Cake Addin #addin nuget:?package=DotNetConfig.CommandLine&version=1.2.0 // Install DotNetConfig.CommandLine as a Cake Tool #tool nuget:?package=DotNetConfig.CommandLine&version=1.2.0
dotnet-config
<p> <b><a href="#why">为什么</a></b> | <b><a href="#what">是什么</a></b> | <b><a href="#who">谁</a></b> | <b><a href="#how">如何</a></b> | <b><a href="#format">格式</a></b> | <b><a href="#api">API</a></b> | <b><a href="#cli">CLI</a></b> </p>
为什么
dotnet-config(或.netconfig)提供了一种统一的机制,让.NET Core 工具可以在可预测的格式中存储和读取配置值,这些值可以通过命令行工具、API 来操作,也可以让用户在任意文本编辑器中手动操作。
与gitconfig提供对所有git命令的一��贯设置存储方式类似,dotnet-config的目标是让所有.NET工具保持一致的水平。格式(主要是)与它兼容,因此利用了git社区关于-config配置的经验教训。
是什么
dotnet-config提供以下内容
- 一种良好的文档格式,可以在任何文本编辑器中手动编辑。
- 一个用于管理配置文件的全局工具(类似于gitconfig)。
- 一个API,供.NET工具作者读取/写入设置。
默认情况下,配置文件的名称为.netconfig,并支持四个存储级别
- 本地:与“Default”级别并列的.netconfig.user文件。
- 默认:当前目录及其任何父目录。
- 全局:用户配置文件目录,来自System.Environment.SpecialFolder.UserProfile。
- 系统:系统目录,来自System.Environment.SpecialFolder.System。
将按照上述顺序读取文件,找到的第一个值具有优先权。当读取多个值时,将返回所有文件中键的所有值。
可以使用.netconfig.user来将本地设置与团队设置分开保留在版本控制中,它已经是.gitignore中常用的被忽略扩展。
谁
以下是一些利用.netconfig提供灵活配置持久性选项的工具。
在我们的文档网站的谁部分了解有关各种工具如何利用.netconfig
的更多信息。
如何
格式
示例文件
# .netconfig is awesome: https://dotnetconfig.org
[serve]
port = 8080
gzip #shorthand for gzip=true
[vs "alias"]
comexp = run|community|exp
preexp = run|preview|exp
[file]
# example of multi-valued variables
url = https://github.com/dotnet/runtime/tree/master/docs/design/features
url = https://github.com/dotnet/aspnetcore/tree/master/docs
; subsections allow grouping variables
[file "docs/design/features/code-versioning.md"]
url = https://github.com/dotnet/runtime/blob/master/docs/design/features/code-versioning.md
etag = 7405567...
[file "docs/APIReviewProcess.md"]
url = https://github.com/dotnet/aspnetcore/blob/master/docs/APIReviewProcess.md
etag = 1e4acd7...
[mytool]
description = "\t tab and \n newline escapes, plus \\ backslash are valid"
title = My tool is great # internal whitespace preserved without needing double quotes
path = C:\\tool # backslashes always escaped, inside or outside double quotes
size = 500kb # numbers can have a multiplier (case insensitive) suffix kb, mb, gb, tb
max-size = 1T # the 'b' is optional.
compress = true # multiple variants for boolean: true|false|yes|no|on|off|1|0
secure = yes
localized = off
enabled = 1
; array like syntax for complex objects
[myArray "0"] # indecies must be unique
description = 1st item description
name = Fero
[myArray "1"]
description = 2nd item description
name = Jozo
语法紧密遵循git-config语法。《#》或《;》字符开始注释,直到行尾,空白行将被忽略。
文件由部分和变量组成。部分以方括号中指定的部分名称开头,并继续到下一个部分开始。部分名称不区分大小写。部分名称只允许字母数字字符和《-》。
部分可以进一步分为子部分。要开始一个子部分,将其名称放入双引号中,用空格与部分名称分开,在部分标题中,如以下示例所示
[section "subsection"]
子部分名称是区分大小写的,可以包含除换行符以外的任何字符。双引号《"`和反斜杠《\》可以通过转义它们作为《\"`和《\\》来包含。
部分标题不能跨越多行。变量可以直接属于部分或给定的子部分。如果您有《[section "subsection"]》,则可以具有《[section]》,但不一定是必需的。
所有其他行都被识别为变量设置,形式为《name = value》(或只是《name》,这是一种简短的说法,表示变量是布尔值《true》)。
对《name =》后面的前导空白字符、行中第一个注释字符《#》或《;》后面的行剩余部分以及行的尾部空白字符都将丢弃,除非它们包含在双引号中。保留值中的内部空白字符。
反斜杠《\》字符必须始终用《\\》转义。双引号必须用《\"`转义或将它们正确配对,这将保留其中的空白字符。
除了《\"`、`\
`以外,只有用于换行符的《\n
`》和用于水平制表符的《\t
`》转义序列被识别。
注意:当使用CLI或API时,这些转义规则会被自动应用。
值
许多变量的值被当作简单的字符串处理,但有变量需要特定类型的值,并且有关如何拼写它们的规则。
布尔值
当一个变量的值被说是具有 布尔 类型时,许多与
true
和false
同义的值被接受;这些值都是不区分大小写的。true:布尔类型的真值可以是
yes
、on
、true
和1
。另外,未定义等于值的变量将被视为true
。false:布尔类型的假值包括
no
、off
、false
、0
和空字符串。
datetime
此类型的变量总是使用 ISO 8601 (或 往返) 格式解析/写入。
number
许多指定各种大小的变量的值可以后缀为
k
、M
、G
或T
,分别表示 "将数字按 1024 缩放"、"按 1024x1024 缩放"、"按 1024x1024x1024 缩放" 或 "按 1024x1024x1024x1024 缩放"。后缀是不区分大小写的,也可以包含b
,如kb
或MB
。
复杂对象数组
通过子部分可以创建数组中更复杂的对象。假设我们有以下配置对象
public class WatchedProcess
{
public string Name { get; set; }
public string ApplicationPath { get; set; }
}
我们希望从配置中检索为 IList<WatchedProcess>
。即使 git-config 语法不支持此场景,我们也可以通过子部分和 ConfigurationRoot 创建复杂对象的列表。
ConfigurationRoot
通过创建用于项目的索引为 "子部分" 以支持与数组的协同工作。这允许我们创建一个部分选择器,该选择器根据数组中的元素索引从数组中选取值。例如,WatchedProcess:0:Name
会选择数组的第一个项目中 Name
的值。这意味着我们可以使用索引作为子部分,创建复杂对象的数组,如下所示
[WatchedProcesses "0"] # indicies must be unique
ApplicationPath = "C:\\MyProcessPath\ABCD"
Name = NServiceBus.Host
[WatchedProcesses "1"] # indicies must be unique
ApplicationPath = "C:\\MyProcessPath2\ABCD"
Name = NServiceBus.Host
[WatchedProcesses "2"] # indicies must be unique
ApplicationPath = "C:\\MyProcessPath2\ABCD"
Name = NServiceBus.Host
有了这个配置,我们就能够以下述方式检索复杂对象的数组
var configurationBuilder = new ConfigurationBuilder();
configurationBuilder.AddDotNetConfig();
var configurationRoot = configurationBuilder.Build();
var watchedProcesses = configurationRoot.GetSection(nameof(WatchedProcess)).Get<IList<Json.Appsettings.WatchedProcess>>();
注意:请确保您的数组项目具有唯一的索引
API
访问 .netconfig 值主要有三种方式
- 本地 API 用于直接访问 .netconfig 值
- Microsoft.Extensions.Configuration 供应商
- System.CommandLine 用于 CLI 应用
本地 API
PM> Install-Package DotNetConfig
.NET 工具作者消耗 DotNetConfig API 的主要用途是首先从特定路径(如果省略则假设当前目录)构建配置
var config = Config.Build();
生成的配置将包含当前目录(或给定路径)中设置的分层变量,以及所有其祖先目录、全局和系统位置。
获取值时,支持的原始类型作为 Add
、Get
和 Set
的第一级方法公开,因此您可以每个 Boolean
、DateTime
、Number
和 String
获得相当多的可用重载,如 AddBoolean
、GetDateTime
、GetString
或 SetNumber
// reads from:
// [mytool]
// enabled = true
bool? enabled = config.GetBoolean("mytool", "enabled");
// reads from:
// [mytool.editor]
// path = code.exe
string? path = config.GetString("mytool.editor", "path");
// reads from:
// [mytool "src/file.txt"]
// createdOn = 2020-08-23T12:00:00Z
DateTime? created = config.GetDateTime("mytool", "src/file.txt", "createdOn");
// If value was not found, set it to the current datetime
if (created == null)
// Would create the section if it did not previously exist, and add the variable
config.SetDateTime("mytool", "src/file.txt", "createdOn", DateTime.Now);
您还可以使用 TryGetXXX
方法,以避免在变量(在请求的部分和可选的子部分)未找到时检查 null 返回值
if (!config.TryGetDateTime("mytool", "src/file.txt", "createdOn", out created))
config.SetDateTime("mytool", "src/file.txt", "createdOn", DateTime.Now);
由于 .netconfig
支持多值变量,您可以通过返回 ConfigEntry
获取所有条目,并对其进行详细的检查或操作
foreach (ConfigEntry entry in config.GetAll("proxy", "url"))
{
// entry.Level allows inspecting the location where the entry was read from
if (entry.Level == ConfigLevel.System)
// entry came from Environment.SpecialFolder.System
else if (entry.Level == ConfigLevel.Global)
// entry came from Environment.SpecialFolder.UserProfile
else if (entry.Level == ConfigLevel.Local)
// entry came from .netconfig.user file in the current dir or an ancestor directory
else
// local entry from current dir .netconfig or an ancestor directory
Console.WriteLine(entry.GetString());
// entry.GetBoolean(), entry.GetDateTime(), entry.GetNumber()
}
在写入值(通过 AddXXX
或 SetXXX
)时,您可以通过传递 ConfigLevel
可选地指定要用于持久化值的配置级别
// writes on the global .netconfig in the user's profile
//[vs "alias"]
// comexp = run|community|exp
config.AddString("vs", "alias", "comexp", "run|community|exp", ConfigLevel.Global);
您可以在 API 站点 中探索整个 API。
Microsoft.Extensions.Configuration
PM> Install-Package DotNetConfig.Configuration
使用说明(在这个例子中,还链接其他提供者)
var config = new ConfigurationBuilder()
.AddJsonFile(...)
.AddEnvironmentVariables()
.AddIniFile(...)
.AddDotNetConfig();
给出以下 .netconfig
[serve]
port = 8080
[security "admin"]
timeout = 60
您可以使用
string port = config["serve:port"]; // == "8080";
string timeout = config["security:admin:timeout"]; // == "60";
System.CommandLine
鉴于将 .netconfig 作为 dotnet (全局) 工具的第一公民的明确目标,它提供了与 System.CommandLine 的出色且无缝的集成。
假设您创建了一个名为 package
的 CLI 应用,它管理您的包本地缓存(即 NuGet)。您可能有一些命令,如 download
和 prune
,如下所示
var root = new RootCommand
{
new Command("download")
{
new Argument<string>("id")
},
new Command("prune")
{
new Argument<string>("id"),
new Option<int>("days")
},
}.WithConfigurableDefaults("package");
添加的 WithConfigurableDefaults
调用意味着现在所有参数和选项都可以在配置文件中指定默认值,例如
[package]
id = DotNetConfig
[package "prune"]
days = 30
注意 id
也可以在顶级指定。集成将自动将可配置值提升到祖先部分,只要它们具有兼容的类型(在 download
和 prune
命令中定义的 id
均为 string
)。
现在,从命令行运行 package -?
将从配置文件中获取渲染的默认值,因此您可以看到在没有提供值的情况下运行命令时会使用什么
Usage:
package [options] [command]
Options:
--version Show version information
-?, -h, --help Show help and usage information
Commands:
download <id> [default: DotNetConfig]
prune <id> [default: DotNetConfig]
而 package prune -?
会对以下值进行显示
Usage:
package [options] prune [<id>]
Arguments:
<id> [default: DotNetConfig]
Options:
--days <days> [default: 30]
-?, -h, --help Show help and usage information
由于 .netconfig 支持多值变量,因此它非常适合填充可以指定多次的参数或选项的默认值。通过上述参数的简单修改
new Argument<string[]>("id")
现在我们可以支持以下配置
[package]
id = DotNetConfig
id = Moq
id = ThisAssembly
如果命令没有 id
参数,执行命令现在将使处理器接收到所有三个参数。您也可以通过例如 download -?
验证这一点
Usage:
package [options] download [<id>...]
Arguments:
<id> [default: DotNetConfig|Moq|ThisAssembly]
Options:
-?, -h, --help Show help and usage information
System.CommandLine 支持 System.CommandLine 的所有支持的多参数和选项类型都会自动填充:数组、IEnumerable
、ICollection
、IList
和 List
。
对于数字,参数/选项可以是 long
或 int
。请注意,由于在 .netconfig 中的数字始终为 long
,因此后者可能会导致截断。
CLI
命令行工具允许您检查和修改用于 dotnet 工具的配置文件。安装方式与任何其他 dotnet 工具相同
> dotnet tool install -g dotnet-config
可用的选项和操作(大部分)与 git config
的行为兼容。
当从单个文件中读取和写入时,您的大部分操作可以使用
git config
,并使用兼容性选项-f|--file
指定读取/写入文件的文件。
读取和写入变量不需要任何特殊选项。以下行首先写入一个变量值,然后检索它的值
> dotnet config mytool.myvariable myvalue
> dotnet config mytool.myvariable
myvalue
值将以原样通过标准输出返回,因此您可以直接将其分配给一个变量,例如。
现在运行 dotnet config -?
的所有当前选项是
Usage: dotnet config [options]
Location (uses all locations by default)
--global use global config file
--system use system config file
--local use .netconfig.user file
-f, --file use given config file (git config compat)
--path[=VALUE] use given config file or directory
Action
--get get value: name [value-regex]
--get-all get all values: key [value-regex]
--get-regexp get values for regexp: name-regex [value-regex]
--add add a new variable: name value
--unset remove a variable: name [value-regex]
--unset-all remove all matches: name [value-regex]
--set set value: name value [value-regex]
--set-all set all matches: name value [value-regex]
--rename-section rename section: old-name new-name
--remove-section remove a section: name
-l, --list list all
-e, --edit edit the config file in an editor
Other
--name-only show variable names only
--default[=VALUE] with --get, use default value when missing entry
--type[=VALUE] value is given this type, can be 'boolean', '
datetime' or 'number'
-?, -h, --help Display this help
命令行解析使用了 Mono.Options,因此以下所有形式的参数都受支持:-flag
、--flag
、/flag
、-flag=value
、--flag=value
、/flag=value
、-flag:value
、--flag:value
、/flag:value
、-flag value
、--flag value
、/flag value
。
赞助商
产品 | 版本 兼容的和额外的目标框架版本。 |
---|---|
.NET | net5.0 已计算。 net5.0-windows 已计算。 net6.0 已计算。 net6.0-android 已计算。 net6.0-ios 已计算。 net6.0-maccatalyst 已计算。 net6.0-macos 已计算。 net6.0-tvos 已计算。 net6.0-windows 已计算。 net7.0 已计算。 net7.0-android 已计算。 net7.0-ios 已计算。 net7.0-maccatalyst 已计算。 net7.0-macos 已计算。 net7.0-tvos 已计算。 net7.0-windows 已计算。 net8.0 已计算。 net8.0-android 已计算。 net8.0-browser 已计算。 net8.0-ios 已计算。 net8.0-maccatalyst 已计算。 net8.0-macos 已计算。 net8.0-tvos 已计算。 net8.0-windows 已计算。 |
.NET Core | netcoreapp2.0 已计算。 netcoreapp2.1 已计算。 netcoreapp2.2 已计算。 netcoreapp3.0 已计算。 netcoreapp3.1 已计算。 |
.NET Standard | netstandard2.0 兼容。 netstandard2.1 已计算。 |
.NET Framework | net461 已被计算 net462 已被计算 net463 已被计算 net47 已被计算 net471 已被计算 net472 已被计算 net48 已被计算 net481 已被计算 |
MonoAndroid | monoandroid 已被计算 |
MonoMac | monomac 已被计算 |
MonoTouch | monotouch 已被计算 |
Tizen | tizen40 已被计算 tizen60 已被计算 |
Xamarin.iOS | xamarinios 已被计算 |
Xamarin.Mac | xamarinmac 已被计算 |
Xamarin.TVOS | xamarintvos 已被计算 |
Xamarin.WatchOS | xamarinwatchos 已被计算 |
-
.NETStandard 2.0
- DotNetConfig (>= 1.2.0)
- System.CommandLine (>= 2.0.0-beta1.21308.1)
NuGet 包
此包没有被任何 NuGet 包使用。
GitHub 仓库
此包没有被任何流行的 GitHub 仓库使用。