Skip to content

Instantly share code, notes, and snippets.

@tinomen
Created April 9, 2011 02:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tinomen/911039 to your computer and use it in GitHub Desktop.
Save tinomen/911039 to your computer and use it in GitHub Desktop.
Service Locator Pattern - remove the explicit references to external class names. *** I had it in my head to write something that would provide the basics of the service locator pattern. While this will provide all services without error it still leaves t
puts __FILE__
require "../service_locator.rb"
require "test/unit"
class TestServiceRegistry < Test::Unit::TestCase
def test_registry
reg = Service::Registry.new
assert_not_nil(reg)
assert_nil(reg[:bob])
reg.register(:foo){"TEST"}
assert_equal("TEST", reg[:foo])
end
def test_registry_builder
b = Service::Builder.new
b.foo{"TEST1"}
assert_equal("TEST1", b.registry[:foo])
end
def test_registry_define
locator = Service::Registry.define do |b|
b.bar{BarTest.new(locator)}
b.foo{FooTest.new(locator)}
end
bar = locator[:bar]
assert_instance_of(BarTest, bar)
foo = locator[:foo]
assert_instance_of(FooTest, foo)
assert_same(bar, foo.bar)
end
class FooTest
attr_reader :bar
def initialize(locator)
@bar = locator[:bar]
end
end
class BarTest
def initialize(locator)
end
end
end
module Service
class Registry
def initialize
@services = {}
end
def self.define
builder = Builder.new
yield builder
builder.registry
end
def register(name, &block)
name = name.intern if name.respond_to? :intern
@services[name] = block
end
def[](key)
if @services.has_key?(key)
@services[key] = @services[key].call if @services[key].is_a? Proc
@services[key]
end
end
end
class Builder
attr_reader :registry
def initialize(reg=nil)
reg ||= Registry.new
@registry = reg
end
def method_missing(service_name, &block)
if block_given?
@registry.register(service_name, &block)
end
nil
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment