
Product
Introducing Socket MCP for Claude Desktop
Add secure dependency scanning to Claude Desktop with Socket MCP, a one-click extension that keeps your coding conversations safe from malicious packages.
# Gemfile:
gem 'rails-ioc'
# config/dependencies/development.rb:
RailsIOC::Dependencies.define do
prototype :card_validator, CreditCardValidator, "Visa", "Mastercard"
prototype :payment_gateway, DummyPaymentGateway, ref(:card_validator)
controller PaymentsController, {
payment_gateway: ref(:payment_gateway),
}
end
# app/controllers/payments_controller.rb:
class PaymentsController < ApplicationController
def accept_payment
@payment_gateway.process(params[:credit_card])
end
end
# spec/controllers/payments_controller_spec.rb
it "processes a succesful payment" do
controller_dependencies(payment_gateway: mock(PaymentGateway))
controller.payment_gateway.should_receive(:process).with("4111").and_return(true)
post :accept_payment, credit_card: "4111"
response.status.should == 200
end
Inversion of control via dependency injection is widely used in large software systems and is generally accepted to be a "Good Thing". If the terms are unfamiliar these are good places to start reading:
The practice as described in the articles above is not particularly common in Ruby applications. Jamis Buck, author of the erstwhile DI framework Copland makes a compelling argument against it. If you have to ask the question "Will I need IOC for my next Rails app", the answer is almost certainly "No". The core components of a standard Rails app usually interact politely and can generally be easily tested.
Still, having run into several Rails projects which dealt with dependencies beyond an ActiveRecord database connection (payment gateways, email services, version control systems, image processing services and more) I realised that I was reminiscing fondly about Java and .NET's various containers for two reasons:
RailsIOC attempts to make these problems less painful for applications with complex interactions with external services by providing a lightweight way to define dependencies and inject them into ActionController. The patterns will be familiar to anyone who has used Spring or Unity. Dependencies are defined in pure Ruby using a simple internal DSL. Where possible, RailsIOC enforces constructor injection. The exception to this rule is the creation of controllers, where it avoids interfering with Rails' own instantiation and injects dependencies as @local_variables.
# Controller:
@gateway = Gateway.new(ServiceA.new, ServiceB.new)
@gateway.do_something!
# RSpec:
@svc_a = mock(ServiceA)
@svc_b = mock(ServiceB)
ServiceA.stub(:new).and_return(@svc_a)
ServiceB.stub(:new).and_return(@svc_b)
@gateway = mock(Gateway)
@gateway.should_receive(:do_something!).and_return(12345)
Gateway.stub(:new).with(@svc_a, @svc_b).and_return(@gateway)
# Controller:
@gateway.do_something!
# RSpec:
controller_dependencies(gateway: mock(Gateway))
controller.gateway.should_receive(:do_something!).and_return(12345)
# app/controllers/payments_controller.rb:
class PaymentsController < ApplicationController
def accept_payment
if Rails.env.development? || Rails.env.test?
@credit_card_validator = BogusCardValidator.new
else
@credit_card_validator = RealCardValidator.new
end
if Rails.env.production?
@gateway = RealPaymentGateway.new
elsif Rails.env.staging?
@gateway = RealPaymentGateway.new(use_testing_url: true)
else
@gateway = BogusPaymentGateway.new
end
card = @credit_card_validator.validate(params[:card])
@gateway.process(card)
end
end
# app/controllers/payments_controller:
class PaymentsController < ApplicationController
def accept_payment
card = @credit_card_validator.validate(params[:card])
@gateway.process(card)
end
end
# config/dependencies/production.rb:
RailsIOC::Dependencies.define do
prototype :payment_gateway, RealPaymentGateway
prototype :credit_card_validator, RealCardValidator
controller PaymentsController, {
gateway: ref(:payment_gateway)
credit_card_validator: ref(:credit_card_validator)
}
end
# config/dependencies/staging.rb:
RailsIOC::Dependencies.define do
inherit_environment(:production)
prototype :payment_gateway, RealPaymentGateway, {use_testing_url: true}
end
# config/dependencies/development.rb:
RailsIOC::Dependencies.define do
inherit_environment(:production)
singleton :payment_gateway, BogusPaymentGateway
singleton :credit_card_validator, BogusCardValidator
end
FAQs
Unknown package
We found that rails-ioc demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
Add secure dependency scanning to Claude Desktop with Socket MCP, a one-click extension that keeps your coding conversations safe from malicious packages.
Product
Socket now supports Scala and Kotlin, bringing AI-powered threat detection to JVM projects with easy manifest generation and fast, accurate scans.
Application Security
/Security News
Socket CEO Feross Aboukhadijeh and a16z partner Joel de la Garza discuss vibe coding, AI-driven software development, and how the rise of LLMs, despite their risks, still points toward a more secure and innovative future.