Summary
Several leader-election options properties are declared init-only. The DI registration extensions configure options through an Action<TOptions> callback (services.Configure(configureOptions)), which receives an already-constructed instance. Assigning to an init-only property outside an object initializer is a compile error, so these properties cannot be set through the documented options => { ... } configuration pattern — the code simply won't build for consumers who try.
This was found while documenting the v2.0.0 Consul SessionLockDelay breaking change (PR #144): the README example originally used options.SessionLockDelay = ..., which doesn't compile for exactly this reason.
Affected properties
| Provider |
File |
init-only properties |
| Consul |
ConsulLeaderElectionOptions.cs |
Datacenter, KeyPrefix, SessionTtl, SessionLockDelay |
| PostgreSQL |
PostgreSQLLeaderElectionOptions.cs |
AutoCreateTable, CommandTimeoutSeconds |
| Azure Blob Storage |
AzureBlobStorageLeaderElectionOptions.cs |
AutoCreateContainer, LeaseDuration |
Note: the semaphore options classes (ConsulSemaphoreOptions, etc.) already use set and are not affected — this is limited to the older leader-election options.
Reproduction
builder.Services.AddConsulLeaderElection(options =>
{
options.SessionLockDelay = TimeSpan.FromSeconds(10); // CS8852: init-only property cannot be assigned here
});
Current workarounds
- Configuration binding works, because the binder sets properties via reflection (which can invoke
init accessors):
builder.Services.Configure<ConsulLeaderElectionOptions>(
builder.Configuration.GetSection("Consul"));
- Constructing the options directly via an object initializer (outside the
Action<T> overload).
Suggested fix
Change these init accessors to set so they behave consistently with the rest of each options class (which already mixes set properties like Address and Token) and with the semaphore options. This makes the Action<TOptions> configure callback — the pattern shown throughout the README — actually usable for every property.
Since changing init → set only widens what's allowed, it is source- and binary-compatible for existing consumers; a good candidate to fold into the v2.0.0 release. If instead the immutability is intentional, the DI extensions and README should be updated to steer users to configuration binding / object-initializer construction for these properties.
Filed from the PR #144 review discussion.
Summary
Several leader-election options properties are declared
init-only. The DI registration extensions configure options through anAction<TOptions>callback (services.Configure(configureOptions)), which receives an already-constructed instance. Assigning to aninit-only property outside an object initializer is a compile error, so these properties cannot be set through the documentedoptions => { ... }configuration pattern — the code simply won't build for consumers who try.This was found while documenting the v2.0.0 Consul
SessionLockDelaybreaking change (PR #144): the README example originally usedoptions.SessionLockDelay = ..., which doesn't compile for exactly this reason.Affected properties
init-only propertiesConsulLeaderElectionOptions.csDatacenter,KeyPrefix,SessionTtl,SessionLockDelayPostgreSQLLeaderElectionOptions.csAutoCreateTable,CommandTimeoutSecondsAzureBlobStorageLeaderElectionOptions.csAutoCreateContainer,LeaseDurationNote: the semaphore options classes (
ConsulSemaphoreOptions, etc.) already usesetand are not affected — this is limited to the older leader-election options.Reproduction
Current workarounds
initaccessors):Action<T>overload).Suggested fix
Change these
initaccessors tosetso they behave consistently with the rest of each options class (which already mixessetproperties likeAddressandToken) and with the semaphore options. This makes theAction<TOptions>configure callback — the pattern shown throughout the README — actually usable for every property.Since changing
init→setonly widens what's allowed, it is source- and binary-compatible for existing consumers; a good candidate to fold into the v2.0.0 release. If instead the immutability is intentional, the DI extensions and README should be updated to steer users to configuration binding / object-initializer construction for these properties.Filed from the PR #144 review discussion.