inject-dependencies
Use this skill when injecting dependencies into Hanami 2.x components.
Core principle: Dependencies are injected, not looked up. Never access the container directly — always use include Deps[].
Quick Reference
| Scenario | Approach |
|---|---|
| Inject a dependency | include Deps["repos.user_repo"] |
| Inject multiple dependencies | include Deps["repos.user_repo", "views.users.index"] |
| Access injected dependency | Call the method name matching the last segment of the key: user_repo |
| Auto-registered key | File app/repos/user_repo.rb → key "repos.user_repo" |
| Exclude from auto-registration | Add path to no_auto_register_paths in the slice config |
| Test with stubs | Pass stubbed dependencies when instantiating the component |
| Override dependency | Pass the dependency as a keyword argument to .new |
Core Rules
Always use
include Deps[]to inject dependencies:# app/actions/users/index.rb # frozen_string_literal: true module MyApp module Actions module Users class Index < MyApp::Action include Deps["repos.user_repo"] def handle(request, response) # `view` is resolved by Hanami from the Action class name convention response.render(view, users: user_repo.all) end end end end endThe container key is derived from the file path:
app/repos/user_repo.rb → "repos.user_repo" app/views/users/index.rb → "views.users.index" app/relations/users.rb → "relations.users"Rule:
app/{dir}/{name}.rbmaps to container key"{dir}.{name}".Certain directories are excluded from auto-registration because ROM manages them directly:
relations/structs/entities/
These are handled by ROM and should not be auto-registered by dry-system.
Add custom exclusions in the slice configuration:
# config/app.rb # frozen_string_literal: true module MyApp class App < Hanami::App config.no_auto_register_paths = ["app/serializers"] end endOverride dependencies in tests by passing them to
.new:stub_repo = double("user_repo", all: []) action = MyApp::Actions::Users::Index.new(user_repo: stub_repo)Never access the container directly:
# BAD repo = Hanami.app["repos.user_repo"] # GOOD include Deps["repos.user_repo"] # use user_repo directly
Anti-Patterns & Mistakes
| Mistake | Correct Approach |
|---|---|
Hanami.app['key'] inside an Action |
Direct container access is untestable. Always use include Deps[]. |
| Guessing container keys | Keys follow app/{dir}/{name}.rb → "{dir}.{name}". Learn the rule, do not guess. |
Auto-registering relations/, structs/, or entities/ |
These are managed by ROM. Adding them to auto-registration causes boot errors. |
Custom initialize for dependency injection |
Deps mixin handles constructor injection for you. Do not write custom initialize methods for DI. |
| Forgetting to update tests after renaming a file | When you move a file, the container key changes. Update all Deps[] references and test stubs. |
| Accessing the full key name as a method | Access by the last segment only: include Deps["repos.user_repo"] → use user_repo. |