Providers are useful when:
- you need to set up a dependency that requires non-trivial configuration (often a third party library, or some library-like code in your
lib
directory)
Providers should be placed in the config/providers
directory. Here’s an example provider for that registers a client for an imagined third-party Acme Email delivery service.
The above provider creates an instance of Acme’s email client, using an API key from our application’s settings, then registers the client in the app container with the key "email_client"
.
Every provider has a name (Hanami.app.register_provider(:my_provider_name)
) and will usually register one or more related components with the relevant container.
Registered components can be any kind of object - they can be classes too.
To register an item with the container, providers call register
, which takes two arguments: the key to be used, and the item to register under it.
- prepare - basic setup code, here you can require third-party code, or code from your
lib
directory, and perform basic configuration - stop - code that needs to run to stop a component, perhaps to close a database connection, or purge some artifacts.
A provider’s prepare and start steps will run as necessary when a component that the provider registers is used by another component at runtime.
Hanami.boot
calls start
on each of your application’s providers, meaning each of your providers is started automatically when your application boots. Similarly, Hanami.shutdown
can be invoked to call stop
on each provider.
You can also trigger lifecycle transitions directly by using Hanami.app.prepare(:provider_name)
, and Hanami.app.stop(:provider_name)
.
Accessing the container via target
This is useful if your provider needs to use other components within the container, for example the application’s settings or logger (via target["settings]
and target["logger"]
). It can also be used when a provider wants to ensure another provider has started before starting itself, via target.start(:provider_name)
: