Background and motivation
Microsoft.Extensions.Configuration.Ini can currently read INI files through AddIniFile and AddIniStream, but it does not provide a supported way to write changes back to an INI file.
Several applications need to edit INI files that are shared with another program or tool. In those cases, overwriting the whole file from a flattened configuration dictionary is risky because unmanaged sections, unmanaged keys, ordering, and value quoting can be lost. A writable provider should support the familiar IConfiguration shape while preserving existing INI content that the caller does not manage.
The motivating scenario for the prototype is editing Classic VICE-style INI resources, where numeric values are commonly bare and string values may be quoted. The same pattern applies to other INI-backed application settings.
API Proposal
namespace Microsoft.Extensions.Configuration;
public static partial class WritableIniConfigurationExtensions
{
public static IConfigurationBuilder AddWritableIniFile(
this IConfigurationBuilder builder,
string path,
bool optional = true);
}
namespace Microsoft.Extensions.Configuration.Ini;
public sealed partial class WritableIniConfigurationSource : IConfigurationSource
{
public required string Path { get; set; }
public bool Optional { get; set; }
public IConfigurationProvider Build(IConfigurationBuilder builder);
}
public sealed partial class WritableIniConfigurationProvider : ConfigurationProvider
{
public WritableIniConfigurationProvider(WritableIniConfigurationSource source);
public string Path { get; }
public override void Load();
public void SetValue(string section, string key, string value, bool? quote = null);
public void Save();
}
public sealed partial class IniDocument
{
public IniDocument();
public IReadOnlyList<string> Sections { get; }
public static IniDocument Parse(string text);
public string? Get(string section, string key);
public void Set(string section, string key, string value, bool? quote = null);
public bool Remove(string section, string key);
public IReadOnlyList<(string Key, string Value)> Entries(string section);
public string ToIniString();
public override string ToString();
}
IniDocument is included in the prototype as the editable document model used by the provider. It is reasonable for API review to decide whether that type should remain public or become an internal implementation detail behind the provider API.
API Usage
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.Ini;
IConfiguration config = new ConfigurationBuilder()
.AddWritableIniFile("settings.ini", optional: true)
.Build();
string? existing = config["C64SC:VICIIModel"];
var source = new WritableIniConfigurationSource
{
Path = "settings.ini",
Optional = true,
};
var provider = (WritableIniConfigurationProvider)source.Build(new ConfigurationBuilder());
provider.Load();
provider.SetValue("C64SC", "VICIIModel", "1");
provider.SetValue("C64SC", "WIC64IPAddress", "192.168.0.1", quote: true);
provider.Save();
The provider preserves unmanaged sections and keys while updating caller-managed values. When quote is null, updates preserve the existing entry's quote style; new entries default to bare values.
Direct document usage, if accepted as public API:
IniDocument document = IniDocument.Parse(File.ReadAllText("settings.ini"));
document.Set("C64SC", "VICIIModel", "1");
document.Set("C64SC", "WIC64IPAddress", "192.168.0.1", quote: true);
File.WriteAllText("settings.ini", document.ToIniString());
Alternative Designs
- Add write support to
IniConfigurationProvider directly. This would change the shape of the existing provider and may be more disruptive than adding an explicit writable provider.
- Expose only
WritableIniConfigurationProvider and keep IniDocument internal. This reduces public API surface but prevents callers from using the lossless document model directly.
- Provide a broader write abstraction for all file-backed configuration providers. That is likely larger than the INI-specific need and would require a wider design discussion.
- Save through
IConfigurationRoot or IConfigurationProvider.Set only. This does not give callers a way to express quote preservation or force quoted output for specific values.
Risks
- Public write support needs clear semantics for formatting preservation. The prototype preserves sections, keys, order, and value quoting, but does not preserve comments or blank-line layout on save.
- Adding
IniDocument as public API increases the reviewed surface area. If the API review prefers a smaller surface, it can be internalized before the implementation PR proceeds.
- INI syntax is loosely defined. The proposed implementation intentionally follows the existing provider's parsing behavior where possible.
required string Path follows the prototype but may need adjustment if API review prefers constructor parameters or nullable property patterns consistent with existing configuration sources.
Implementation prototype: #128987
Background and motivation
Microsoft.Extensions.Configuration.Inican currently read INI files throughAddIniFileandAddIniStream, but it does not provide a supported way to write changes back to an INI file.Several applications need to edit INI files that are shared with another program or tool. In those cases, overwriting the whole file from a flattened configuration dictionary is risky because unmanaged sections, unmanaged keys, ordering, and value quoting can be lost. A writable provider should support the familiar
IConfigurationshape while preserving existing INI content that the caller does not manage.The motivating scenario for the prototype is editing Classic VICE-style INI resources, where numeric values are commonly bare and string values may be quoted. The same pattern applies to other INI-backed application settings.
API Proposal
IniDocumentis included in the prototype as the editable document model used by the provider. It is reasonable for API review to decide whether that type should remain public or become an internal implementation detail behind the provider API.API Usage
The provider preserves unmanaged sections and keys while updating caller-managed values. When
quoteisnull, updates preserve the existing entry's quote style; new entries default to bare values.Direct document usage, if accepted as public API:
Alternative Designs
IniConfigurationProviderdirectly. This would change the shape of the existing provider and may be more disruptive than adding an explicit writable provider.WritableIniConfigurationProviderand keepIniDocumentinternal. This reduces public API surface but prevents callers from using the lossless document model directly.IConfigurationRootorIConfigurationProvider.Setonly. This does not give callers a way to express quote preservation or force quoted output for specific values.Risks
IniDocumentas public API increases the reviewed surface area. If the API review prefers a smaller surface, it can be internalized before the implementation PR proceeds.required string Pathfollows the prototype but may need adjustment if API review prefers constructor parameters or nullable property patterns consistent with existing configuration sources.Implementation prototype: #128987