Skip to content

Instantly share code, notes, and snippets.

@wojtha
Last active December 3, 2015 17:32
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wojtha/322ddfe6323b647e4fc3 to your computer and use it in GitHub Desktop.
Save wojtha/322ddfe6323b647e4fc3 to your computer and use it in GitHub Desktop.
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