injecting-dependencies
Skill0 starsChanged 51 days agoMITView on GitHub
Use when writing a constructor or initialiser, when a type needs a collaborator to do its work, or when adding a parameter so something can be swapped in a test.
In this repository20 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- templates/CLAUDE.mdCLAUDE.md
- capturing-decisionsSkill
- choosing-subagent-modelsSkill
- committing-changesSkill
- debugging-systematicallySkill
- delegating-workSkill
- designing-changesSkill
- exploring-a-codebaseSkill
- planning-changesSkill
- pruning-testsSkill
- reflecting-on-changesSkill
- resolving-conflictsSkill
- reviewing-codeSkill
- verifying-changesSkill
- writing-commentsSkill
- writing-logsSkill
- writing-project-instructionsSkill
- writing-skillsSkill
- writing-testsSkill
The file
We split this skill into the rules it gives an agent
3 rules. About 0 are common, 3 are distinctive, and 0 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 33
When a test needs to see something a type builds internally, move the construction to the call site.
- Distinctive: line 40
When two collaborators must share the identical object — a cache for a reader and a writer, a session for two clients — bind it to a local …
- Distinctive: line 54
Every dependency in the signature is one a reader sees, a test replaces and a change traces.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Injecting dependencies
A complex collaborator is a required parameter. Services, engines, controllers, coordinators, repositories, clients — whoever configures the object supplies them, not the object itself.
- Defaults are for simple leaves: a scheduler, a clock, a timer source, a formatter — no dependencies of their own, and the default is the answer rather than a guess.
The sentinel default is the anti-pattern
init(engine: Engine? = nil) {
self.engine = engine ?? Engine(...) // ← this
}nil here means "construct it yourself" — the one thing the parameter existed to prevent.
- The dependency is invisible. Nothing at the call site says this type needs an
Engine. - Two construction paths. Production takes one, tests the other, so the shipped path is the least exercised.
- The default outlives its reason, and nothing fails when it stops being right.
- The constraint is the signal. A default that would need another parameter's value to build is the language saying the object cannot construct this itself. Pass it in.
Move construction, do not add an escape hatch
- When a test needs to see something a type builds internally, move the construction to the call site. Do not add a parameter only tests use — the test then verifies the path nobody ships.
- Move the
new/initto whoever already decides how the object is configured; test and production become one path.
Two parameters that must be one instance
When two collaborators must share the identical object — a cache for a reader and a writer, a session for two clients — bind it to a local at the call site and pass it to both:
let session = Session(...)
let reader = Reader(session: session)
let writer = Writer(session: session)The sharing is visible where it is established. Constructing twice, or documenting the requirement in a comment, leaves it for a refactor to break silently.
What this buys
- Every dependency in the signature is one a reader sees, a test replaces and a change traces.
- Wiring moves out to a composition point — where that knowledge belongs.
- A parameter list that feels too long is information: the type has too many responsibilities. Defaults hide the evidence, not the responsibilities.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

