elastic / elastic/docs-builder

chore: Remove single-implementation C# interfaces

Open
#3,569 1 comment 0 reactions 0 assignees View on GitHub
chore needs triage tech-debt
Dominant language
C#
Stars
24
Forks
44
Avg merge
1d 7h
Merged PRs (30d)
146

Description

## What

Remove interfaces that have exactly one implementation and no test mocks — they add indirection with no polymorphism benefit.

## Interfaces to remove

| Interface | Single impl | File |
|-----------|-------------|------|
| `IFormatter` | `IrregularSpaceFormatter` | `src/authoring/Elastic.Documentation.Refactor/Formatters/IFormatter.cs` |
| `IPagesProvider` | `LocalPagesProvider` | `src/Elastic.Documentation.LegacyDocs/PagesProvider.cs` |
| `IHtmxAttributeProvider` | `DefaultHtmxAttributeProvider` | `src/Elastic.Documentation.Site/Htmx.cs` |
| `IDescriptionGenerator` | `DescriptionGenerator` — every caller already passes `new DescriptionGenerator()` | `src/Elastic.Markdown/DescriptionGenerator.cs` |
| `IDocumentationFileOutputProvider` | `GlobalNavigationPathProvider` — one optional ctor param consumer | `src/Elastic.Markdown/DocumentationGenerator.cs` |
| `ILinkIndexWriter` + `ILinkIndexReaderWriter` | `AwsS3LinkIndexReaderWriter` — keep `ILinkIndexReader` (2 impls), fold `SaveRegistry` onto the concrete writer | `src/Elastic.Documentation.LinkIndex/ILinkIndexWriter.cs` |
| `IChangesService` | `ChangesService` | `src/services/search/Elastic.Documentation.Search/IChangesService.cs` |
| `IDocumentGateway` | single impl, one consumer | `src/api/Elastic.Documentation.Mcp.Remote/Gateways/IDocumentGateway.cs` |
| `IAskAiMessageFeedbackService` | single impl, one consumer | `src/api/Elastic.Documentation.Api/AskAi/IAskAiMessageFeedbackGateway.cs` |
| `IGitRepository` | `SingleCommitOptimizedGitRepository` — 9-method interface consumed only by same-file helpers that already `new` the concrete type | `src/services/Elastic.Documentation.Assembler/Sourcing/GitFacade.cs` |
| `IProductNameLookup` | `ProductsConfiguration` — depend on the config record directly | `src/services/search/Elastic.Documentation.Search.Contract/Common/IProductNameLookup.cs` |
| `ISitemapParser`, `IAdaptiveCrawler`, `IDocumentExporter` | one impl each; `AddHttpClient` needs no interface | `src/tooling/essc/LabsCrawl/` |
| `IChangelogMarkdownRenderer` | redundant with `MarkdownRendererBase`, which all 6 renderers derive from; type the list as `List` | `src/services/Elastic.Changelog/Rendering/Markdown/IChangelogMarkdownRenderer.cs` |

**Excluded (correctly polymorphic or test-mocked — do NOT remove):**
- `IDocsSyncPlanStrategy` / `IDocsSyncApplyStrategy` — deliberate named strategy pattern
- `IGitHubReleaseService`, `IGitHubPrService`, `IGcpIdTokenProvider`, `IS3EtagCalculator` — mocked via `A.Fake<>` in `tests/` / `tests-integration/`
- `IRepositoryTracker` — 2 impls (`IntegrationGitRepositoryTracker`, `LocalGitRepositoryTracker`)
- `IParserResolvers` — 2 impls (`ParserResolvers` record, `ParserContext`)
- `IDocumentInferrerService` (2 impls), navigation tree interfaces (`INavigationItem`, `ITableOfContentsItem`, etc. — multiple impls)

## How

For each interface: delete the interface declaration, update all constructor parameters and DI registrations to reference the concrete type directly. Update any `services.AddScoped()` to `services.AddScoped()`.

~180 lines removed across the batch.

> [!NOTE]
> Re-audited 2026-07-07: six interfaces originally listed here (`IGitHubReleaseService`, `IGitHubPrService`, `IGcpIdTokenProvider`, `IS3EtagCalculator`, `IRepositoryTracker`, `IParserResolvers`) were false positives — mocked in tests or with a second implementation — and moved to the excluded list. Thirteen newly verified single-impl interfaces were added.

Part of the broader ponytail over-engineering audit tracked in #3574.

Contributor guide

Open the contributing guide

Research direction

Start with the listed interface files and trace their constructor parameters and DI registrations across the referenced API, service, tooling, and rendering paths. Verify the excluded interfaces remain intact, then run the relevant repository checks. Done means the listed single-implementation interfaces are removed, concrete types are wired directly, and the batch builds and tests pass.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
backend, tooling
Issue type
Refactor
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.