From e2c91cb7a66425f546765de1eafbcda0f1fa3838 Mon Sep 17 00:00:00 2001 From: ArturT Date: Sat, 22 Feb 2014 13:55:43 +0100 Subject: [PATCH 1/2] Add Dependor::Singleton, update readme, add specs --- README.md | 34 +++++++++++++++++++++++++++++- lib/dependor.rb | 1 + lib/dependor/instantiator.rb | 7 +++++- lib/dependor/singleton.rb | 4 ++++ spec/dependor/instantiator_spec.rb | 20 ++++++++++++++++++ 5 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 lib/dependor/singleton.rb diff --git a/README.md b/README.md index 6b7331d..08f8282 100644 --- a/README.md +++ b/README.md @@ -249,7 +249,7 @@ require 'dependor/shorty' class MyInjector include Dependor::AutoInject - + takes :params, :session, :request def foo @@ -274,6 +274,38 @@ class PostsController < ApplicationController end ``` +## Dependor::Singleton + +You can include this to make your service class as a singleton. + +``` +class FooService + include Dependor::Singleton +end + +class MyInjector + include Dependor::AutoInject + + takes :params, :session, :request +end + +class ApplicationController + extend Dependor::Injectable + + def injector + @injector ||= MyInjector.new(params, session, request) + end +end + +class PostsController < ApplicationController + inject :foo_service + + def get + render text: foo_service.object_id == foo_service.object_id # true + end +end +``` + ## Testing Dependor doesn't add any dependencies to your classes so you can test them any way you like. diff --git a/lib/dependor.rb b/lib/dependor.rb index ed08f9c..8e472c1 100644 --- a/lib/dependor.rb +++ b/lib/dependor.rb @@ -10,6 +10,7 @@ module Dependor autoload :Injectable, 'dependor/injectable' autoload :Instantiator, 'dependor/instantiator' autoload :Isolate, 'dependor/isolate' + autoload :Singleton, 'dependor/singleton' autoload :Let, 'dependor/let' autoload :SendingInjector, 'dependor/sending_injector' autoload :Shorty, 'dependor/shorty' diff --git a/lib/dependor/instantiator.rb b/lib/dependor/instantiator.rb index 635feea..5a6d276 100644 --- a/lib/dependor/instantiator.rb +++ b/lib/dependor/instantiator.rb @@ -5,11 +5,16 @@ class Instantiator def initialize(injector, dependency_names) @injector = injector @dependency_names = dependency_names + @singletons = {} end def instantiate(klass) dependencies = dependency_names.for_class(klass).map{|name| @injector.get(name)} - return klass.new(*dependencies) + if klass.include?(Dependor::Singleton) + return @singletons[klass] ||= klass.new(*dependencies) + else + return klass.new(*dependencies) + end end end end diff --git a/lib/dependor/singleton.rb b/lib/dependor/singleton.rb new file mode 100644 index 0000000..a2a5c46 --- /dev/null +++ b/lib/dependor/singleton.rb @@ -0,0 +1,4 @@ +module Dependor + module Singleton + end +end diff --git a/spec/dependor/instantiator_spec.rb b/spec/dependor/instantiator_spec.rb index ca11dfc..f06f7cb 100644 --- a/spec/dependor/instantiator_spec.rb +++ b/spec/dependor/instantiator_spec.rb @@ -35,4 +35,24 @@ def foo instance.foo.should == 'foo-bar-baz' end + + it "instantiates objects as a new object" do + klass = Class.new {} + + first_instance = instantiator.instantiate(klass) + second_instance = instantiator.instantiate(klass) + + first_instance.object_id.should_not == second_instance.object_id + end + + it "instantiates objects as a singleton object" do + klass = Class.new do + include Dependor::Singleton + end + + first_instance = instantiator.instantiate(klass) + second_instance = instantiator.instantiate(klass) + + first_instance.object_id.should == second_instance.object_id + end end From ff3315e6e616c6e1a3dca2d3928535767fb7822c Mon Sep 17 00:00:00 2001 From: ArturT Date: Sat, 22 Feb 2014 13:57:23 +0100 Subject: [PATCH 2/2] add missing ruby for readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 08f8282..d2cfb99 100644 --- a/README.md +++ b/README.md @@ -278,7 +278,7 @@ end You can include this to make your service class as a singleton. -``` +```ruby class FooService include Dependor::Singleton end