dotnet / dotnet/command-line-api
Synergy between Configuration and Option<T>
- Dominant language
- C#
- Stars
- 3.7k
- Forks
- 428
- PR merge metrics
- No merged PRs in 30d
Description
Hi,
Fully aware that this is still a work in progress, I started working on two projects using the libraries of this repository.
- https://github.com/Kralizek/dotnet-ensure-unique/tree/prototype
- https://github.com/Kralizek/Hyde/tree/prototype
In both cases, I got to a point where I would like the `Option` and the `Microsoft.Extensions.Configuration` stack to have stronger synergies.
## `Configuration` => `Option`
It would be nice to have `Option` be aware of the values flowing from the Configuration stack. The concrete use case is that I want to provide some defaults coming from configuration files or from environment variables.
It would be nice if the `getDefaultValue` parameter of the `Option` constructor somehow supported this signature instead `Func`.
## `Option` => `Configuration`
Next, it would be nice if values provided via console commands/arguments/options could be easily used with the `IOptions` system.
For the purpose, I have created this extension method
```csharp
internal static class HostBuilderContextExtensions
{
public static bool TryGetOptionValue(this HostBuilderContext context, Option option, out TValue value)
{
if (context.Properties.TryGetValue(typeof(InvocationContext), out var obj) &&
obj is InvocationContext ctx &&
ctx.ParseResult.HasOption(option) &&
ctx.ParseResult.ValueForOption(option) is TValue optionValue)
{
value = optionValue;
return true;
}
value = default;
return false;
}
}
```
But its usage is a bit clunky
```csharp
services.Configure(options =>
{
if (context.TryGetOptionValue(CommonOptions.BucketNameOption, out string bucketName))
{
options.BucketName = bucketName;
}
if (context.TryGetOptionValue(CommonOptions.FilePrefixOption, out string filePrefix))
{
options.FilePrefix = filePrefix;
}
});
```
Contributor guide
Assessment
This issue has not been assessed yet.