Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Example from Fearless Rails Controller Refactoring using Dry::GetterInject. See https://gist.github.com/wojtha/b9730d108625e04a0642
# rewritten example by using container and autoinject
require 'dry-container'
module MyApp
container = Dry::Container.new
container.register(:metrics_adapter, -> { MetricsAdapter.new(container[:metrics_configuration]) } )
container.register(:metrics_configuration, -> { METRICS_CONFIG.fetch(Rails.env) })
container.register(:create_product_service, -> { CreateProductService.new(container[:metrics_adapter]) })
AutoInject = Dry::GetterInject(container, :private)
def self.Inject(*keys)
AutoInject[*keys]
end
end
class ProductsController
include MyApp::Inject(:create_product_service)
def create
product = create_product_service.(params[:product])
redirect_to product_path(product), notice: "Product created"
rescue CreateProductService::Failed => failure
# ... probably render ...
end
end
# rewritten example by using Rails configuration container and autoinject
require 'delegate'
# Rails configuration
MyApp::Application.configure do |config|
config.metrics_adapter = -> { MetricsAdapter.new(Rails.configuration.metrics_configuration) }
config.metrics_configuration = -> { METRICS_CONFIG.fetch(Rails.env) }
config.create_product_service = -> { CreateProductService.new(Rails.configuration.metrics_adapter) }
end
module MyApp
# We can use adapter or monkeypatch Rails::Application::Configuration
# Handle only simple keys. Throws NoMethodError.
class RailsContaineDecorator < SimpleDelegator
def [](key)
__getobj__.public_send(key)
end
end
# Use Rails.configuration as DI container
container = RailsContainerDecorator.new(Rails.configuration)
AutoInject = Dry::GetterInject(container, :private)
def self.Inject(*keys)
AutoInject[*keys]
end
end
class ProductsController
include MyApp::Inject(:create_product_service)
def create
product = create_product_service.(params[:product])
redirect_to product_path(product), notice: "Product created"
rescue CreateProductService::Failed => failure
# ... probably render ...
end
end
# original example from chapter Instantiating service objects
module CreateProductServiceInjector
def metrics_adapter
@metrics_adapter ||= MetricsAdapter.new(METRICS_CONFIG.fetch(Rails.env))
end
def create_product_service
@create_product_service ||= CreateProductService.new(metrics_adapter)
end
end
class ProductsController
include CreateProductServiceInjector
def create
product = create_product_service.call(params[:product])
redirect_to product_path (product), notice: "Product created"
rescue CreateProductService::Failed => failure
# ... probably render ...
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.