CtrlK
BlogDocsLog inGet started
Tessl Logo

igmarin/hanakai-yaku

Curated library of atomic AI agent skills for Hanami, dry-rb, and ROM Ruby development. Covers actions, slices, repositories, relations, changesets, providers, DI, operations, TDD, CLI, views, routing, and validation. Shared Ruby process skills have moved to ruby-core-skills. Uses Markdown + Front-matter architecture.

92

1.33x
Quality

94%

Does it follow best practices?

Impact

92%

1.33x

Average score across 35 eval scenarios

SecuritybySnyk

Passed

No known issues

Overview
Quality
Evals
Security
Files

SKILL.mdskills/di/register-provider/

name:
register-provider
license:
MIT
description:
Use when registering external dependencies in Hanami 2.x. Creates provider files in config/providers/, configures dependency injection containers, sets up boot sequences with prepare/start lifecycle hooks, and integrates database, mailer, cache, and third-party services into the DI container.
metadata:
{"version":"1.0.0","ecosystem_sources":["dry-rb/dry-system","hanami/hanami"],"tags":["di","providers","container","external-services"]}

register-provider

Use this skill when registering external dependencies (database, mailer, cache, third-party APIs) in the Hanami 2.x DI container.

Core principle: Providers bridge external libraries into the DI container. They handle initialization, configuration, and lifecycle.


Quick Reference

ScenarioApproach
Create a providerbundle exec hanami generate provider <name>
Register a databaseUse the built-in database provider or custom provider
Register a mailerCreate config/providers/mailer.rb
Register a cacheCreate config/providers/cache.rb
Register a third-party API clientCreate config/providers/<service>.rb
Access the provided componentinclude Deps["<provider_name>.<component>"]
Configure the providerUse the prepare and start lifecycle hooks

Core Rules

  1. Generate a provider using the Hanami CLI:

    hanami generate provider mailer

    This creates config/providers/mailer.rb.

  2. Implement the provider using lifecycle hooks: Use prepare for requiring dependencies and start for component initialization. Keep providers focused on a single external dependency or library.

    # config/providers/mailer.rb
    # frozen_string_literal: true
    
    Hanami.app.register_provider(:mailer) do
      prepare do
        require "mail"
      end
    
      start do
        client = Mail.new do
          delivery_method :smtp, {
            address: target[:settings].smtp_host,
            port: target[:settings].smtp_port
          }
        end
    
        register("mailer.client", client)
      end
    end
  3. Access provided components via Deps:

    # app/mailers/welcome.rb
    module MyApp
      module Mailers
        class Welcome
          include Deps["mailer.client"]
    
          def deliver(user)
            client.deliver do
              to user.email
              subject "Welcome!"
            end
          end
        end
      end
    end
  4. Use the built-in database provider: The ROM container is automatically registered at boot by the framework:

    include Deps["db.rom"]
  5. Register third-party API clients using settings: Always load keys and URLs through target[:settings]. Do not reference raw environment variables via ENV in providers.

    # config/providers/logger.rb
    Hanami.app.register_provider(:logger) do
      start do
        require "logger"
        logger = Logger.new(target[:settings].log_file)
        register("logger.client", logger)
      end
    end
  6. Test components that depend on providers by stubbing the provided dependency:

    stub_mailer = double("mailer", deliver: true)
    welcome = MyApp::Mailers::Welcome.new(mailer__client: stub_mailer)
  7. Verify a provider is correctly registered using the Hanami console or a smoke test:

    [WARNING] Rescue and log errors in start. A failed provider should not crash the app boot.

    # In `hanami console`
    Hanami.app["mailer.client"]   # => returns the registered instance
    Hanami.app["logger.client"]   # => returns Logger

    For a lightweight smoke test in specs:

    it "registers the mailer client" do
      expect(Hanami.app["mailer.client"]).to be_a(Mail::Message)
    end

Integration

Related SkillWhen to chain
inject-dependenciesProvided components are injected via Deps[]. Understand Deps before writing providers.
manage-settingsProviders read configuration from target[:settings]. Define settings before writing providers.
create-actionActions inject provided services via Deps[].
create-repositoryThe database provider registers ROM, which Repositories depend on.
integrate-api-clientComplex API clients may need a dedicated skill for auth/patterns.

skills

di

register-provider

README.md

tile.json