TypeConverter and configuration
editConvert with a TypeConverter
The generator adds a TypeConverter to each ID and registers it with [TypeConverter]. Libraries that convert values through TypeDescriptor, such as Microsoft.Extensions.Configuration, MVC model binding and UI frameworks, handle IDs like any simple type:
var converter = TypeDescriptor.GetConverter(typeof(ProjectId));
Assert.Equal(ProjectId.FromInt32(42), converter.ConvertFromInvariantString("42"));
Assert.Equal(ProjectId.FromInt32(42), converter.ConvertFrom(42));
Assert.Equal("42", converter.ConvertToInvariantString(ProjectId.FromInt32(42)));The converter converts:
- from a
string(withParse), the underlying type or the ID itself; - to a
string(ValueAsString), the underlying type or the ID itself.
The culture given to the converter is ignored: the conversion always uses the invariant culture. A string that does not parse throws a FormatException.
Bind configuration
The configuration binder converts the strings of appsettings.json, environment variables and the other configuration sources with the TypeConverter, so an options class can use IDs directly:
public sealed class ImportOptions
{
public ProjectId DefaultProject { get; set; }
public IList<ProjectId> ArchivedProjects { get; } = [];
}var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string?>
{
["Import:DefaultProject"] = "42",
["Import:ArchivedProjects:0"] = "7",
["Import:ArchivedProjects:1"] = "8",
})
.Build();
// The configuration binder converts the strings with the generated TypeConverter
var options = configuration.GetSection("Import").Get<ImportOptions>();
Assert.Equal(ProjectId.FromInt32(42), options!.DefaultProject);
Assert.Equal([ProjectId.FromInt32(7), ProjectId.FromInt32(8)], options.ArchivedProjects);The same options class works with services.Configure<ImportOptions>(...) and IOptions<ImportOptions>.