-
-
Save piclez/4f06923ca120830bc6e45273919768c1 to your computer and use it in GitHub Desktop.
Service locator with Rails Initializer for rails service loader that loads the services from a config file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ListingsController < ApplicationController | |
def index | |
movie_listing_service = ServiceLocator.get_service_instance(:MovieListing) | |
@available_movies = movie_listing_service.available_movies | |
render nothing: true #this is just an example don't get hung up on it :) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#An example rails controller spec using this. Note that in your spec helper you could just have a before(:each) to reset the locator. | |
require "spec_helper" | |
describe ListingsController do | |
describe "GET #index" do | |
it "lists all the movies." do | |
gold_finger = mock("Goldfinger: an Awesome bond movie") | |
ferris_buellers_day_off = mock("Ferris Bueller's Day off") | |
fake_movie_listing_provider_service = mock("Fake Movie Listing Provider Service", available_movies: [gold_finger, ferris_buellers_day_off]) | |
locator = ServiceLocator.instance | |
locator.register(:MovieListingProvider, fake_movie_listing_provider_service) | |
ServiceLocator.load_locator(locator) | |
get :index | |
assigns(:available_movies).should == [gold_finger, ferris_buellers_day_off] | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ServiceLocator | |
include Singleton | |
def self.reset_instance | |
self.instance_variable_set("@singleton__instance__", self.send(:new)) | |
end | |
def initialize | |
@services = {} | |
end | |
#Do this in your setup file | |
def register(service_name, instance) | |
@services[service_name] = instance | |
end | |
def get_service_instance(service_name) | |
service_instance = @services[service_name] | |
raise NoSuchServiceInstanceException if service_instance.nil? | |
service_instance | |
end | |
class NoSuchServiceInstanceException < Exception; end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "active_support/inflector" | |
#Require any gems that contain services that you'd like to use here | |
#eg: require "spacebook_api_services" | |
require "metflix" | |
require_relative File.join(Rails.root,"app/services/metflix_movie_listing_service") #Normally this would probably live in a gem! | |
services = YAML.load_file(File.join(File.expand_path( "..", File.dirname(__FILE__)), "services.yml")) | |
services.each do |service_name, service_info| | |
service_instance = service_info["class"].constantize.new(*service_args) | |
ServiceLocator.register(service_name.to_sym, service_instance) | |
endrequire "active_support/inflector" | |
require_relative File.join(Rails.root,"app/services/metflix_movie_listing_service") #Normally this would probably live in a gem! | |
services = YAML.load_file(File.join(File.expand_path( "..", File.dirname(__FILE__)), "services.yml")) | |
services.each do |service_name, service_info| | |
service_instance = service_info["class"].constantize.new(*service_args) | |
ServiceLocator.register(service_name.to_sym, service_instance) | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "spec_helper" #Could easily live in its own gem and be run/developed outside of rails but I was lazy ;) | |
describe ServiceLocator do | |
describe ".instance" do | |
it "returns the only locator instance for the Service Locator Singleton" do | |
ServiceLocator.instance.should == ServiceLocator.instance | |
end | |
end | |
describe ".reset_instance" do | |
it "sets the locator singleton's only instance to a new locator" do | |
original_instance = ServiceLocator.instance | |
ServiceLocator.reset_instance | |
ServiceLocator.instance.should_not == original_instance | |
end | |
end | |
describe ".get_service_instance" do | |
it "should return a properly constructed instance for the service named by the given symbol" do | |
locator = ServiceLocator.instance #Service locator instance from singleton ;) | |
charlie_horse_service = mock("A properly constructed charlie horse service instance") | |
locator.register(:CharlieHorseService, charlie_horse_service) | |
ServiceLocator.instance.get_service_instance(:CharlieHorseService).should == charlie_horse_service | |
end | |
it "should throw a NoSuchServiceInstance exception if there is no such instance registered with the locator" do | |
expect { ServiceLocator.instance.get_service_instance(:CrazyDataService) }.to raise_exception ServiceLocator::NoSuchServiceInstanceException | |
end | |
end | |
end | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
MovieListing: | |
class: MetFlixMovieListingService | |
args: | |
- abc_123 #api_key | |
- false #sandbox_mode |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment