Railtie for dry-system (つ◕౪◕)つ━☆゚.*・。゚
Installation
Add it to your Gemfile:
gem 'dry-system-rails'
Usage
To configure auto-registration create config/initializers/system.rb
with the following content:
Dry::System::Rails.container do
# you can set it to whatever you want and add as many dirs you want
config.auto_register << 'lib'
end
The Dry::System::Rails::Railtie
creates a container and injector on your behalf at runtime and assign them to two constants Container
and Import
under your applications root module. E.g. if your application is named MyApp
, the Railtie
will add the following constants:
MyApp::Container
MyApp::Import
Now you can use MyApp::Import
to inject components into your objects and framework components:
# lib/user_repo.rb
class UserRepo
end
# lib/create_user.rb
class CreateUser
include MyApp::Import['user_repo']
end
# app/controllers/users_controller.rb
class UsersController < ApplicationController
include MyApp::Import['create_user']
end
Working with Framework Dependencies
The Rails API is designed around the usage of class methods. If you choose to write domain logic in objects you will likely encounter a situation where your code will have to use one of the framework components. That is where manual registration using bootable dependency will come in handy.
E.g. You have an object CreateWidget
that needs to process widgets asynchronously with an Widgets:NotificationJob
but you want to leverage dependency injection to decouple the components:
# config/initializers/system.rb
Dry::System::Rails.container do
# changes `self` to the container
config.auto_register << 'lib'
end
# app/jobs/widgets/notification_job.rb
class Widgets::NotificationJob < ApplicationJob
end
# config/system/boot/application.rb
# Use bootable componets to manually register framework dependencies
MyApp::Container.boot(:application) do |app|
setup do
app.namespace(:widgets) do |widgets|
widgets.register(:notification, memoize: true) { Widgets::NotificationJob }
end
end
end
# lib/create_widget.rb
class CreateWidget
include MyApp::Import[job: 'widgets.notification']
def call(args)
# some logic that creates a widget command
job.perform_later(create_widget_command)
end
end
TODO
This is super alpha and it's missing a couple of things:
- Some generators to make UX nicer
- Tests for loading scripts (console etc)
- Tests for running rake tasks
License
See LICENSE
file.