diff --git a/features/class_injections.feature b/features/class_injections.feature index c8e5f68..020be2d 100644 --- a/features/class_injections.feature +++ b/features/class_injections.feature @@ -41,7 +41,7 @@ Feature: Class Injections """ Then the output should be: """ - "For the King!" - "Welcome to FarFarAway's army, fellow Sword Master." + For the King! + Welcome to FarFarAway's army, fellow Sword Master. """ diff --git a/lib/dependor.rb b/lib/dependor.rb index be4f0d2..945c342 100644 --- a/lib/dependor.rb +++ b/lib/dependor.rb @@ -14,6 +14,10 @@ require "dependor/registry" require "dependor/lookup_chain" +require "dependor/injectable_class" +require "dependor/class_takes_ext" +require "dependor/subclass_builder" + module Dependor def self.registry(&block) Registry.build(&block) @@ -22,4 +26,8 @@ def self.registry(&block) def self.takes(*dependency_names) TakesExt.Takes(*dependency_names) end + + def self.class_takes(*dependency_names) + ClassTakesExt.ClassTakes(*dependency_names) + end end diff --git a/lib/dependor/class_takes_ext.rb b/lib/dependor/class_takes_ext.rb new file mode 100644 index 0000000..bc4ca51 --- /dev/null +++ b/lib/dependor/class_takes_ext.rb @@ -0,0 +1,13 @@ +module Dependor + module ClassTakesExt + module_function + def ClassTakes(*names) + Module.new do + define_singleton_method :extended do |klass| + klass.send(:extend, Dependor::InjectableClass) + klass.add_dependencies(*names) + end + end + end + end +end diff --git a/lib/dependor/injectable_class.rb b/lib/dependor/injectable_class.rb new file mode 100644 index 0000000..7c59e7a --- /dev/null +++ b/lib/dependor/injectable_class.rb @@ -0,0 +1,8 @@ +module Dependor + module InjectableClass + attr_accessor :class_takes + def add_dependencies(*names) + @class_takes = names + end + end +end diff --git a/lib/dependor/instantiator.rb b/lib/dependor/instantiator.rb index 1eeb5dc..4f41333 100644 --- a/lib/dependor/instantiator.rb +++ b/lib/dependor/instantiator.rb @@ -20,6 +20,11 @@ def new(klass_name, overwrites = {}) klass.new(args) end + def get_class(klass_name) + klass = @class_lookup.lookup(klass_name) + SubclassBuilder.subclass(klass, @injector) + end + def method_missing(name, *args, &block) super if args.any? @injector[name] diff --git a/lib/dependor/object_definition.rb b/lib/dependor/object_definition.rb index 3d0f45b..1b26b40 100644 --- a/lib/dependor/object_definition.rb +++ b/lib/dependor/object_definition.rb @@ -5,7 +5,10 @@ def self.default_for(klass) new(klass.name.to_sym, opts, proc{ new(klass) }) end - def self.build(name, transient: false, &block) + def self.build(name, transient: false, as: :instance, &block) + if as == :class + block ||= proc{ get_class(name) } + end block ||= proc{ new(name) } new(name, {transient: transient}, block) end diff --git a/lib/dependor/subclass_builder.rb b/lib/dependor/subclass_builder.rb new file mode 100644 index 0000000..4bbeb67 --- /dev/null +++ b/lib/dependor/subclass_builder.rb @@ -0,0 +1,15 @@ +module Dependor + class SubclassBuilder + def self.subclass(klass, injector) + return klass unless klass.respond_to?(:class_takes) + + Class.new(klass) do + klass.class_takes.each do |dependency| + define_singleton_method dependency do + injector[dependency] + end + end + end + end + end +end