Skip to content

feat: fill interface parameters from the one registered implementation - #34

Merged
jackielii merged 1 commit into
mainfrom
feat/di-interface-params
Oct 16, 2026
Merged

jackielii merged 1 commit into
mainfrom
feat/di-interface-params

Conversation

@jackielii

@jackielii jackielii commented Oct 16, 2026 •

Copy link
Copy Markdown
Owner

What

An interface-typed parameter on Props, ServeHTTP, Init or Middlewares is now filled by the single WithArgs registration that implements it. A page can then declare a narrow consumer-side interface, and a unit test can call Props directly with a fake.

type userLister interface{ ListUsers(context.Context) ([]User, error) }

func (usersPage) Props(r *http.Request, users userLister) (UsersProps, error) { … }
// Mount(…, WithArgs(&PostgresStore{})) fills users; a test passes fakeUsers{}.

Matching rules

  1. The per-request values (writer, request, RenderTarget, *PageNode) fill a parameter first.
  2. Otherwise, an interface parameter takes the one registration implementing it. Registrations are keyed by their dynamic type, so there is no "register under an interface" form; a concrete parameter matches as before.
  3. If two or more registrations implement it, that's an error naming them: X is implemented by more than one registered value (A, B); declare the parameter as the concrete type, or narrow the interface.

Startup check

Mount checks every Props and extended ServeHTTP parameter for ambiguity (checkInjection), so the ambiguity fails startup with the page named instead of failing a request. Parse skips the check.

A missing dependency is deliberately not checked at Mount and stays a request-time error, as before. Apps such as eos mount pages in configurations, and tests, that don't register those pages' services.

Behaviour changes

  • Interface parameters that used to fail every request with "not found" are now filled when exactly one registration implements them.
  • An app with an interface parameter implemented by two registrations now fails Mount. Before, every request to that page failed.
  • Nothing else changes: per-request injection is untouched.

Verification

  • go test ./... and golangci-lint are clean.
  • Every example passes go vet and its tests.
  • The full eos suite against this branch, via go.work: 338 packages ok, 0 failures.
  • New tests are in di_interface_test.go. The args_test/generics_injection_test cases were updated for interface filling.

Docs updated: docs/dependency-injection.md, skills/structpages/SKILL.md §7, reference.md, CLAUDE.md.

https://claude.ai/code/session_01Dp3Jmu2ePyCME2yG9yd672

An interface-typed Props/ServeHTTP/Init/Middlewares parameter now takes
the single WithArgs registration that implements it, so a page can
declare a narrow interface and a unit test can call it with a fake. An
exact type registration and the per-request values still win first.

Two registrations implementing the parameter are an error naming both;
Mount checks every Props and extended ServeHTTP parameter for this up
front (checkInjection), so the ambiguity fails startup rather than a
request. Parse skips the check. A missing dependency stays a
request-time error, as before.

Claude-Session: https://claude.ai/code/session_01Dp3Jmu2ePyCME2yG9yd672
@codecov

codecov Bot commented Oct 16, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.87500% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.21%. Comparing base (a296d69) to head (756af74).

Files with missing lines Patch % Lines
parse.go 87.50% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #34      +/-   ##
==========================================
+ Coverage   95.16%   95.21%   +0.04%     
==========================================
  Files          16       16              
  Lines        1490     1547      +57     
==========================================
+ Hits         1418     1473      +55     
- Misses         43       44       +1     
- Partials       29       30       +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@jackielii
jackielii merged commit f2bc9b2 into main Oct 16, 2026
16 checks passed
@jackielii
jackielii deleted the feat/di-interface-params branch October 16, 2026 11:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant