Skip to content

Commit 29a9d10

Browse files
committed
methods strategy
1 parent 53b150d commit 29a9d10

File tree

5 files changed

+121
-19
lines changed

5 files changed

+121
-19
lines changed

lib/dry/auto_inject/strategies.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ def self.register_default(name, strategy)
1919
require 'dry/auto_inject/strategies/args'
2020
require 'dry/auto_inject/strategies/hash'
2121
require 'dry/auto_inject/strategies/kwargs'
22+
require 'dry/auto_inject/strategies/methods'
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# frozen_string_literal: true
2+
3+
module Dry
4+
module AutoInject
5+
class Strategies
6+
# @api private
7+
class Base < Module
8+
ClassMethods = Class.new(Module)
9+
InstanceMethods = Class.new(Module)
10+
11+
attr_reader :container
12+
attr_reader :dependency_map
13+
attr_reader :instance_mod
14+
attr_reader :class_mod
15+
16+
def initialize(container, *dependency_names)
17+
@container = container
18+
@dependency_map = DependencyMap.new(*dependency_names)
19+
@instance_mod = InstanceMethods.new
20+
@class_mod = ClassMethods.new
21+
end
22+
23+
# @api private
24+
def included(klass)
25+
klass.send(:include, instance_mod)
26+
klass.extend(class_mod)
27+
28+
super
29+
end
30+
end
31+
end
32+
end
33+
end

lib/dry/auto_inject/strategies/constructor.rb

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,19 @@
11
# frozen_string_literal: true
22

3+
require 'dry/auto_inject/strategies/base'
34
require 'dry/auto_inject/dependency_map'
45

56
module Dry
67
module AutoInject
78
class Strategies
8-
class Constructor < Module
9-
ClassMethods = Class.new(Module)
10-
InstanceMethods = Class.new(Module)
11-
12-
attr_reader :container
13-
attr_reader :dependency_map
14-
attr_reader :instance_mod
15-
attr_reader :class_mod
16-
17-
def initialize(container, *dependency_names)
18-
@container = container
19-
@dependency_map = DependencyMap.new(*dependency_names)
20-
@instance_mod = InstanceMethods.new
21-
@class_mod = ClassMethods.new
22-
end
23-
9+
class Constructor < Base
2410
# @api private
2511
def included(klass)
2612
define_readers
2713

2814
define_new
2915
define_initialize(klass)
3016

31-
klass.send(:include, instance_mod)
32-
klass.extend(class_mod)
33-
3417
super
3518
end
3619

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# frozen_string_literal: true
2+
3+
require 'dry/auto_inject/strategies/base'
4+
require 'dry/auto_inject/method_parameters'
5+
6+
module Dry
7+
module AutoInject
8+
class Strategies
9+
# @api private
10+
class Methods < Base
11+
# @api private
12+
def included(klass)
13+
define_class_methods
14+
define_instance_methods
15+
16+
super
17+
end
18+
19+
private
20+
21+
def define_class_methods
22+
class_mod.class_exec(container, dependency_map) do |container, dependency_map|
23+
dependency_map.to_h.each do |name, identifier|
24+
define_method name do
25+
container[identifier]
26+
end
27+
end
28+
29+
def with_deps(**deps)
30+
Class.new(self) do |klass|
31+
deps.each do |name, value|
32+
singleton_class.define_method name do
33+
value
34+
end
35+
end
36+
end
37+
end
38+
end
39+
40+
self
41+
end
42+
43+
def define_instance_methods
44+
instance_mod.class_exec(container, dependency_map) do |container, dependency_map|
45+
dependency_map.to_h.each do |name, identifier|
46+
define_method name do
47+
self.class.send(name)
48+
end
49+
end
50+
end
51+
52+
self
53+
end
54+
end
55+
56+
register :methods, Methods
57+
end
58+
end
59+
end

spec/integration/methods_spec.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# frozen_string_literal: true
2+
3+
require 'pry'
4+
5+
RSpec.describe 'methods' do
6+
it 'defines methods returning dependencies' do
7+
module Test
8+
AutoInject = Dry::AutoInject(one: 'dep 1', two: 'dep 2').methods
9+
end
10+
11+
obj = Class.new do
12+
include Test::AutoInject[:one, :two]
13+
end
14+
15+
expect(obj.one).to eq 'dep 1'
16+
expect(obj.new.one).to eq 'dep 1'
17+
expect(obj.two).to eq 'dep 2'
18+
expect(obj.new.two).to eq 'dep 2'
19+
20+
other_obj = obj.with_deps(one: 'other dep 1')
21+
expect(other_obj.one).to eq 'other dep 1'
22+
expect(other_obj.new.one).to eq 'other dep 1'
23+
expect(other_obj.two).to eq 'dep 2'
24+
expect(other_obj.new.two).to eq 'dep 2'
25+
end
26+
end

0 commit comments

Comments
 (0)