BrighterCommand / BrighterCommand/Brighter
Six configuration options are public fields rather than properties, so property-based tooling and binders cannot see them
- Dominant language
- C#
- Stars
- 2.5k
- Forks
- 296
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 21
Description
## What
Six reader-facing configuration options are declared as **public mutable instance fields** rather than properties. Every one of them sits in a class whose other members are properties, which is what makes them look like oversights rather than decisions.
| Type | Member | File |
|---|---|---|
| `AzureServiceBusSubscriptionConfiguration` | `public string SqlFilter` | `AzureServiceBusSubscriptionConfiguration.cs:67` |
| `AzureServiceBusSubscriptionConfiguration` | `public bool UseServiceBusQueue` | `AzureServiceBusSubscriptionConfiguration.cs:72` |
| `AzureServiceBusPublication` | `public bool UseServiceBusQueue` | `AzureServiceBusPublication.cs:39` |
| `AzureBlobLockingProviderOptions` | `public Func StorageLocationFunc` | `AzureBlobLockingProviderOptions.cs:50` |
| `AzureBlobArchiveProviderOptions` | `public Func StorageLocationFunc` | `AzureBlobArchiveProviderOptions.cs:62` |
| `AzureBlobArchiveProviderOptions` | `public Func> TagsFunc` | `AzureBlobArchiveProviderOptions.cs:50` |
In `AzureServiceBusSubscriptionConfiguration` the two fields follow six properties in the same class; in `AzureBlobLockingProviderOptions` the field follows three; in `AzureBlobArchiveProviderOptions` the two follow six. On `AzureServiceBusPublication` the field is the type's only declared member.
## Verified
- Present at tag **`10.7.0`** and on **`origin/master`** today.
- **No `ref`, `out` or `in` usage** of any of the six anywhere in `src/`, `tests/` or `samples/`, and none is looked up by name via reflection. Every use is a plain read or an object-initialiser write, so changing them to properties is **source-compatible across the whole repository**.
- Swept two ways and made to agree: reflection over the packages, and a source sweep of every `public` declaration in `src/`. These six are the only public mutable instance fields on configuration types. (A seventh, `RelationalDbConnectionProvider.Instance`, is a diagnostic `Guid` rather than a configuration option.)
## Why it matters
They are invisible to anything that enumerates properties, which is the normal way to reflect over an options type:
- Tooling that reads `Type.GetProperties()` — including the checker I maintain for the Brighter documentation — sees `AzureServiceBusSubscriptionConfiguration` as a six-option type when it is an eight-option one. That is how I found these.
- I have not tested it against this code, but property-based configuration binders (including `Microsoft.Extensions.Configuration`'s) bind public **properties** and ignore fields, so `SqlFilter` and `UseServiceBusQueue` would not be settable from `appsettings.json` the way their six neighbours are.
- A field cannot later gain validation, a computed default, or an `init` accessor without a binary-breaking change — which is the same change proposed here, only made later and under pressure.
## Suggested change
Convert all six to auto-properties, preserving the initialisers:
```csharp
public string SqlFilter { get; set; } = string.Empty;
public bool UseServiceBusQueue { get; set; } = false;
public Func StorageLocationFunc { get; set; } = (resource) => $"lock-{resource}";
```
**Compatibility note, stated plainly:** this is source-compatible everywhere in this repository, but a field-to-property change is **binary-breaking** for any pre-compiled external assembly that reads or writes these members. That is a judgement call for a minor-version boundary, not something I can settle from outside.
## What I could not determine
Whether any of the six is deliberate. Nothing in the surrounding code or the XML comments distinguishes them from their property neighbours, and I have not found a discussion of it — but "it looks accidental" is an inference, not a measurement, so I have not assumed it.
Related but distinct: #4269 covers ASB queue creation ignoring `SubscriptionConfiguration`, which touches one of the same types for a different reason.
Reported from the documentation side while writing option tables for `AzureServiceBusConfiguration.md`; `src/` is outside the scope I am authorised to change, so this is a report rather than a PR.
Contributor guide
Research direction
Inspect AzureServiceBusSubscriptionConfiguration.cs, AzureServiceBusPublication.cs, AzureBlobLockingProviderOptions.cs, and AzureBlobArchiveProviderOptions.cs, comparing the listed fields with neighboring properties and their object-initializer uses. Run the relevant tests and verify that all six members are properties with their existing initializers preserved and no repository usages regress.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- azure, csharp
- Domain
- backend, cloud
- Issue type
- Refactor
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100