dry-auto_inject 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 59c074194d93b68ca4f6f5556cb2e50b6b613bb4
4
- data.tar.gz: 2441a44b97fba6eceecbe97404f75e52367020eb
3
+ metadata.gz: 5c8a5ebc379dd91da33ab5b74b37b8b5233ce496
4
+ data.tar.gz: 530f763d2a088affcfba27591b4b414b0005b1e5
5
5
  SHA512:
6
- metadata.gz: 7696fa4ae133db3ee5d2e80bbdd9b293eaf9aa5ab4dab1993ef35280ab82262bbfb3778cba933b722043de629919826f27dcc1c39b4db1d610d5d57fd9f7e707
7
- data.tar.gz: 9d896a2cffcf233531d32b02f9c3d91288db46659236b53538993969427974bda1222cd90cb124de2b5249c5d235330b4c15a2337327bc4f0a47c2d2f5f1fe06
6
+ metadata.gz: fb55775c7a465d2f796e56421c6098abef986ea5c177b18851e4ba2cce6111bbdf8dad8fd873d52072e674901e7fcaeac23a304cae5cd6198e0581f7c5d32c6a
7
+ data.tar.gz: 0c9c3d0012f2978420fa74fd536eed7c77cdf0d579d85a28afb05d79399f02d31e770b31718679babe16befc8c1a3de22df0635bda5ef495f2475b12c69e0378
data/.travis.yml CHANGED
@@ -8,8 +8,7 @@ rvm:
8
8
  - 2.0
9
9
  - 2.1
10
10
  - 2.2
11
- - rbx-2
12
- - jruby
11
+ - rbx
13
12
  - ruby-head
14
13
  - jruby-head
15
14
  env:
@@ -17,6 +16,7 @@ env:
17
16
  - JRUBY_OPTS='--dev -J-Xmx1024M'
18
17
  matrix:
19
18
  allow_failures:
19
+ - rvm: rbx
20
20
  - rvm: ruby-head
21
21
  - rvm: jruby-head
22
22
  notifications:
data/CHANGELOG.md CHANGED
@@ -1,3 +1,89 @@
1
+ # v.0.3.0, 2016-06-02
2
+
3
+ ### Added
4
+
5
+ * Support for new `kwargs` and `hash` injection strategies
6
+
7
+ These strategies can be accessed via methods on the main builder object:
8
+
9
+ ```ruby
10
+ MyInject = Dry::AutoInect(my_container)
11
+
12
+ class MyClass
13
+ include MyInject.hash["my_dep"]
14
+ end
15
+ ```
16
+ * Support for user-provided injection strategies
17
+
18
+ All injection strategies are now held in their own `Dry::AutoInject::Strategies` container. You can add register your own strategies to this container, or choose to provide a strategies container of your own:
19
+
20
+ ```ruby
21
+ class CustomStrategy < Module
22
+ # Your strategy code goes here :)
23
+ end
24
+
25
+ # Registering your own strategy (globally)
26
+ Dry::AutoInject::Strategies.register :custom, CustomStrategy
27
+
28
+ MyInject = Dry::AutoInject(my_container)
29
+
30
+ class MyClass
31
+ include MyInject.custom["my_dep"]
32
+ end
33
+
34
+ # Providing your own container (keeping the existing strategies in place)
35
+ class MyStrategies < Dry::AutoInject::Strategies
36
+ register :custom, CustomStrategy
37
+ end
38
+
39
+ MyInject = Dry::AutoInject(my_container, strategies: MyStrategies)
40
+
41
+ class MyClass
42
+ include MyInject.custom["my_dep"]
43
+ end
44
+
45
+ # Proiding a completely separated container
46
+ class MyStrategies
47
+ extend Dry::Container::Mixin
48
+ register :custom, CustomStrategy
49
+ end
50
+
51
+ MyInject = Dry::AutoInject(my_container, strategies: MyStrategies)
52
+
53
+ class MyClass
54
+ include MyInject.custom["my_dep"]
55
+ end
56
+ ```
57
+ * User-specified aliases for dependencies
58
+
59
+ These aliases enable you to specify your own name for dependencies, both for their local readers and their keys in the kwargs- and hash-based initializers. Specify aliases by passing a hash of names:
60
+
61
+ ```ruby
62
+ MyInject = Dry::AutoInect(my_container)
63
+
64
+ class MyClass
65
+ include MyInject[my_dep: "some_other.dep"]
66
+
67
+ # Refer to the dependency as `my_dep` inside the class
68
+ end
69
+
70
+ # Pass your own replacements using the `my_dep` initializer key
71
+ my_obj = MyClass.new(my_dep: something_else)
72
+ ```
73
+
74
+ A mix of both regular and aliased dependencies can also be injected:
75
+
76
+ ```ruby
77
+ include MyInject["some_dep", another_dep: "some_other.dep"]
78
+ ```
79
+
80
+ * Inspect the `super` method of the including class’s `#initialize` and send it arguments that will match its own arguments list/arity. This allows auto_inject to be used more easily in existing class inheritance heirarchies.
81
+
82
+ ### Changed
83
+
84
+ * `kwargs` is the new default injection strategy
85
+ * Rubinius support is not available for the `kwargs` strategy (see [#18](https://github.com/dry-rb/dry-auto_inject/issues/18))
86
+
1
87
  # v0.2.0 2016-02-09
2
88
 
3
89
  ### Added
data/Gemfile CHANGED
@@ -5,8 +5,5 @@ gemspec
5
5
 
6
6
  group :tools do
7
7
  gem 'byebug', platforms: :mri
8
- gem 'rubocop'
9
- gem 'guard'
10
- gem 'guard-rspec'
11
- gem 'guard-rubocop'
8
+ gem 'pry'
12
9
  end
data/README.md CHANGED
@@ -1,10 +1,18 @@
1
- # Dry::AutoInject <a href="https://gitter.im/dryrb/chat" target="_blank">![Join the chat at https://gitter.im/dryrb/chat](https://badges.gitter.im/Join%20Chat.svg)</a>
2
-
3
- <a href="https://rubygems.org/gems/dry-auto_inject" target="_blank">![Gem Version](https://badge.fury.io/rb/dry-auto_inject.svg)</a>
4
- <a href="https://travis-ci.org/dryrb/dry-auto_inject" target="_blank">![Build Status](https://travis-ci.org/dryrb/dry-auto_inject.svg?branch=master)</a>
5
- <a href="https://gemnasium.com/dryrb/dry-auto_inject" target="_blank">![Dependency Status](https://gemnasium.com/dryrb/dry-auto_inject.svg)</a>
6
- <a href="https://codeclimate.com/github/dryrb/dry-auto_inject" target="_blank">![Code Climate](https://codeclimate.com/github/dryrb/dry-auto_inject/badges/gpa.svg)</a>
7
- <a href="http://inch-ci.org/github/dryrb/dry-auto_inject" target="_blank">![Documentation Status](http://inch-ci.org/github/dryrb/dry-auto_inject.svg?branch=master&style=flat)</a>
1
+ [gitter]: https://gitter.im/dry-rb/chat
2
+ [gem]: https://rubygems.org/gems/dry-auto_inject
3
+ [travis]: https://travis-ci.org/dry-rb/dry-auto_inject
4
+ [gemnasium]: https://gemnasium.com/dry-rb/dry-auto_inject
5
+ [code_climate]: https://codeclimate.com/github/dry-rb/dry-auto_inject
6
+ [inch]: http://inch-ci.org/github/dry-rb/dry-auto_inject
7
+
8
+ # dry-auto_inject [![Join the Gitter chat](https://badges.gitter.im/Join%20Chat.svg)][gitter]
9
+
10
+ [![Gem Version](https://img.shields.io/gem/v/dry-auto_inject.svg)][gem]
11
+ [![Build Status](https://img.shields.io/travis/dry-rb/dry-auto_inject.svg)][travis]
12
+ [![Dependency Status](https://img.shields.io/gemnasium/dry-rb/dry-auto_inject.svg)][gemnasium]
13
+ [![Code Climate](https://img.shields.io/codeclimate/github/dry-rb/dry-auto_inject.svg)][code_climate]
14
+ [![API Documentation Coverage](http://inch-ci.org/github/dry-rb/dry-auto_inject.svg)][inch]
15
+ ![No monkey-patches](https://img.shields.io/badge/monkey--patches-0-brightgreen.svg)
8
16
 
9
17
  A simple extensions which allows you to automatically inject dependencies to your
10
18
  object constructors from a configured container.
@@ -73,5 +81,5 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
73
81
 
74
82
  ## Contributing
75
83
 
76
- Bug reports and pull requests are welcome on GitHub at https://github.com/dryrb/dry-auto_inject.
84
+ Bug reports and pull requests are welcome on GitHub at https://github.com/dry-rb/dry-auto_inject.
77
85
 
data/bin/console CHANGED
@@ -1,14 +1,10 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'bundler/setup'
4
- require 'dry/pipeline'
4
+ require 'dry-auto_inject'
5
5
 
6
6
  # You can add fixtures and/or initialization code here to make experimenting
7
7
  # with your gem easier. You can also use a different console, if you like.
8
8
 
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require 'irb'
14
- IRB.start
9
+ require 'pry'
10
+ Pry.start
@@ -17,6 +17,10 @@ Gem::Specification.new do |spec|
17
17
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
18
18
  spec.require_paths = ['lib']
19
19
 
20
+ spec.required_ruby_version = '>= 2.0.0'
21
+
22
+ spec.add_runtime_dependency 'dry-container', '~> 0.3.4'
23
+
20
24
  spec.add_development_dependency 'bundler'
21
25
  spec.add_development_dependency 'rake'
22
26
  spec.add_development_dependency 'rspec'
@@ -1,4 +1,4 @@
1
- require 'dry/auto_inject/version'
1
+ require 'dry/auto_inject/builder'
2
2
 
3
3
  module Dry
4
4
  # Configure an auto-injection module
@@ -38,151 +38,15 @@ module Dry
38
38
  # @return [Proc] calling the returned proc builds an auto-injection module
39
39
  #
40
40
  # @api public
41
- def self.AutoInject(container)
42
- Injection.new(container)
41
+ def self.AutoInject(container, options = {})
42
+ AutoInject::Builder.new(container, options)
43
43
  end
44
44
 
45
- class Injection
46
- attr_reader :container, :options
47
-
48
- # @api private
49
- def initialize(container, options = {})
50
- @container = container
51
- @options = options
52
- end
53
-
54
- # @api public
55
- def hash
56
- self.class.new(container, options.merge(type: :hash))
57
- end
58
-
59
- # @api public
60
- def [](*names)
61
- AutoInject.new(names, container, options)
62
- end
63
- end
64
-
65
- # @api private
66
- class AutoInject < Module
67
- attr_reader :names
68
-
69
- attr_reader :container
70
-
71
- attr_reader :instance_mod
72
-
73
- attr_reader :ivars
74
-
75
- attr_reader :options
76
-
77
- attr_reader :type
78
-
79
- # @api private
80
- def initialize(names, container, options = {})
81
- @names = names
82
- @container = container
83
- @options = options
84
- @type = options.fetch(:type, :args)
85
- @ivars = names.map(&:to_s).map { |s| s.split('.').last }.map(&:to_sym)
86
- @instance_mod = Module.new
87
- define_constructor
88
- end
89
-
90
- # @api private
91
- def included(klass)
92
- define_readers
93
- define_new_method(klass)
94
- define_container(klass)
95
-
96
- klass.send(:include, instance_mod)
97
-
98
- super
99
- end
100
-
101
- private
102
-
103
- # @api private
104
- def define_container(klass)
105
- klass.instance_variable_set('@container', container)
106
-
107
- klass.class_eval do
108
- def self.container
109
- if superclass.respond_to?(:container)
110
- superclass.container
111
- else
112
- @container
113
- end
114
- end
115
- end
116
- end
117
-
118
- # @api private
119
- def define_new_method(klass)
120
- case type
121
- when :args then define_new_method_with_args(klass)
122
- when :hash then define_new_method_with_hash(klass)
123
- end
124
- end
125
-
126
- # @api private
127
- def define_new_method_with_args(klass)
128
- klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
129
- def self.new(*args)
130
- names = [#{names.map(&:inspect).join(', ')}]
131
- deps = names.map.with_index { |_, i| args[i] || container[names[i]] }
132
- super(*deps)
133
- end
134
- RUBY
135
- end
136
-
137
- # @api private
138
- def define_new_method_with_hash(klass)
139
- klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
140
- def self.new(options = {})
141
- names = [#{names.map(&:inspect).join(', ')}]
142
- deps = names.each_with_object({}) { |k, r|
143
- r[k.to_s.split('.').last.to_sym] = options[k] || container[k]
144
- }.merge(options)
145
- super(deps)
146
- end
147
- RUBY
148
- end
149
-
150
- # @api private
151
- def define_constructor
152
- case type
153
- when :args then define_constructor_with_args
154
- when :hash then define_constructor_with_hash
155
- end
156
- end
157
-
158
- # @api private
159
- def define_constructor_with_args
160
- instance_mod.class_eval <<-RUBY, __FILE__, __LINE__ + 1
161
- def initialize(*args)
162
- super()
163
- #{ivars.map.with_index { |name, i| "@#{name} = args[#{i}]" }.join("\n")}
164
- end
165
- RUBY
166
- self
167
- end
168
-
169
- # @api private
170
- def define_constructor_with_hash
171
- instance_mod.class_eval <<-RUBY, __FILE__, __LINE__ + 1
172
- def initialize(options)
173
- super()
174
- #{ivars.map { |name| "@#{name} = options[:#{name}]" }.join("\n")}
175
- end
176
- RUBY
177
- self
178
- end
179
-
45
+ module AutoInject
180
46
  # @api private
181
- def define_readers
182
- instance_mod.class_eval <<-RUBY, __FILE__, __LINE__ + 1
183
- attr_reader #{ivars.map { |name| ":#{name}" }.join(', ')}
184
- RUBY
185
- self
47
+ def self.super_method(klass, method)
48
+ method = klass.instance_method(method)
49
+ method unless method.owner.equal?(klass)
186
50
  end
187
51
  end
188
52
  end
@@ -0,0 +1,31 @@
1
+ require 'dry/auto_inject/strategies'
2
+ require 'dry/auto_inject/injector'
3
+
4
+ module Dry
5
+ module AutoInject
6
+ class Builder
7
+ # @api private
8
+ attr_reader :container
9
+
10
+ # @api private
11
+ attr_reader :strategies
12
+
13
+ def initialize(container, options = {})
14
+ @container = container
15
+ @strategies = options.fetch(:strategies) { Strategies }
16
+
17
+ strategies.keys.each do |strategy_name|
18
+ define_singleton_method(strategy_name) do
19
+ strategy = strategies[strategy_name]
20
+ Injector.new(container, strategy)
21
+ end
22
+ end
23
+ end
24
+
25
+ # @api public
26
+ def [](*dependency_names)
27
+ default[*dependency_names]
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,44 @@
1
+ module Dry
2
+ module AutoInject
3
+ DuplicateDependencyError = Class.new(StandardError)
4
+
5
+ class DependencyMap
6
+ def initialize(*dependencies)
7
+ @map = {}
8
+
9
+ dependencies = dependencies.dup
10
+ aliases = dependencies.last.is_a?(Hash) ? dependencies.pop : {}
11
+
12
+ dependencies.each do |identifier|
13
+ name = identifier.to_s.split(".").last
14
+ add_dependency(name, identifier)
15
+ end
16
+
17
+ aliases.each do |name, identifier|
18
+ add_dependency(name, identifier)
19
+ end
20
+ end
21
+
22
+ def inspect
23
+ @map.inspect
24
+ end
25
+
26
+ def names
27
+ @map.keys
28
+ end
29
+
30
+ def to_h
31
+ @map.dup.to_h
32
+ end
33
+ alias_method :to_hash, :to_h
34
+
35
+ private
36
+
37
+ def add_dependency(name, identifier)
38
+ name = name.to_sym
39
+ raise DuplicateDependencyError, "name +#{name}+ is already used" if @map.key?(name)
40
+ @map[name] = identifier
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,23 @@
1
+ require 'dry/auto_inject/strategies'
2
+
3
+ module Dry
4
+ module AutoInject
5
+ class Injector
6
+ # @api private
7
+ attr_reader :container
8
+
9
+ # @api private
10
+ attr_reader :strategy
11
+
12
+ # @api private
13
+ def initialize(container, strategy)
14
+ @container = container
15
+ @strategy = strategy
16
+ end
17
+
18
+ def [](*dependency_names)
19
+ strategy.new(container, *dependency_names)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,19 @@
1
+ require 'dry-container'
2
+
3
+ module Dry
4
+ module AutoInject
5
+ class Strategies
6
+ extend Dry::Container::Mixin
7
+
8
+ # @api public
9
+ def self.register_default(name, strategy)
10
+ register name, strategy
11
+ register :default, strategy
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+ require 'dry/auto_inject/strategies/args'
18
+ require 'dry/auto_inject/strategies/hash'
19
+ require 'dry/auto_inject/strategies/kwargs'
@@ -0,0 +1,71 @@
1
+ require 'dry/auto_inject/strategies/constructor'
2
+
3
+ module Dry
4
+ module AutoInject
5
+ class Strategies
6
+ # @api private
7
+ class Args < Constructor
8
+ private
9
+
10
+ def define_new(klass)
11
+ klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
12
+ def self.new(*args)
13
+ names = #{dependency_map.inspect}
14
+ deps = names.values.map.with_index { |identifier, i| args[i] || container[identifier] }
15
+ super(*deps, *args[deps.size..-1])
16
+ end
17
+ RUBY
18
+ end
19
+
20
+ def define_initialize(klass)
21
+ super_method = find_super(klass, :initialize)
22
+
23
+ if super_method.nil? || super_method.parameters.empty?
24
+ define_initialize_with_params
25
+ else
26
+ define_initialize_with_splat(super_method)
27
+ end
28
+ end
29
+
30
+ def define_initialize_with_params
31
+ initialize_args = dependency_map.names.join(', ')
32
+
33
+ instance_mod.class_eval <<-RUBY, __FILE__, __LINE__ + 1
34
+ def initialize(#{initialize_args})
35
+ super()
36
+ #{dependency_map.names.map { |name| "@#{name} = #{name}" }.join("\n")}
37
+ end
38
+ RUBY
39
+ end
40
+
41
+ def define_initialize_with_splat(super_method)
42
+ super_params = if super_method.parameters.any? { |type, _| type == :rest }
43
+ '*args'
44
+ else
45
+ "*args[0..#{super_method.parameters.length - 1}]"
46
+ end
47
+
48
+ instance_mod.class_eval <<-RUBY, __FILE__, __LINE__ + 1
49
+ def initialize(*args)
50
+ super(#{super_params})
51
+ #{dependency_map.names.map.with_index { |name, i| "@#{name} = args[#{i}]" }.join("\n")}
52
+ end
53
+ RUBY
54
+ end
55
+
56
+ def find_super(klass, method_name)
57
+ super_method = Dry::AutoInject.super_method(klass, method_name)
58
+
59
+ # Look upwards past `def foo(*)` methods until we get an explicit list of parameters
60
+ while super_method && super_method.parameters == [[:rest]]
61
+ super_method = Dry::AutoInject.super_method(super_method.owner, :initialize)
62
+ end
63
+
64
+ super_method
65
+ end
66
+ end
67
+
68
+ register :args, Args
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,60 @@
1
+ require 'dry/auto_inject/dependency_map'
2
+
3
+ module Dry
4
+ module AutoInject
5
+ class Strategies
6
+ class Constructor < Module
7
+ ClassMethods = Class.new(Module) do
8
+ def initialize(container)
9
+ super()
10
+ define_method(:container) { container }
11
+ end
12
+ end
13
+
14
+ InstanceMethods = Class.new(Module)
15
+
16
+ attr_reader :container
17
+ attr_reader :dependency_map
18
+ attr_reader :instance_mod
19
+ attr_reader :class_mod
20
+
21
+ def initialize(container, *dependency_names)
22
+ @container = container
23
+ @dependency_map = DependencyMap.new(*dependency_names)
24
+ @instance_mod = InstanceMethods.new
25
+ @class_mod = ClassMethods.new(container)
26
+ end
27
+
28
+ # @api private
29
+ def included(klass)
30
+ define_readers
31
+
32
+ define_new(klass)
33
+ define_initialize(klass)
34
+
35
+ klass.send(:include, instance_mod)
36
+ klass.extend(class_mod)
37
+
38
+ super
39
+ end
40
+
41
+ private
42
+
43
+ def define_readers
44
+ instance_mod.class_eval <<-RUBY, __FILE__, __LINE__ + 1
45
+ attr_reader #{dependency_map.names.map { |name| ":#{name}" }.join(', ')}
46
+ RUBY
47
+ self
48
+ end
49
+
50
+ def define_new(klass)
51
+ raise NotImplementedError, "must be implemented by a subclass"
52
+ end
53
+
54
+ def define_initialize(klass)
55
+ raise NotImplementedError, "must be implemented by a subclass"
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,38 @@
1
+ require 'dry/auto_inject/strategies/constructor'
2
+
3
+ module Dry
4
+ module AutoInject
5
+ class Strategies
6
+ # @api private
7
+ class Hash < Constructor
8
+ private
9
+
10
+ def define_new(_klass)
11
+ class_mod.class_eval <<-RUBY, __FILE__, __LINE__ + 1
12
+ def new(options = {})
13
+ names = #{dependency_map.inspect}
14
+ deps = names.each_with_object({}) { |(name, identifier), obj|
15
+ obj[name] = options[name] || container[identifier]
16
+ }.merge(options)
17
+ super(deps)
18
+ end
19
+ RUBY
20
+ end
21
+
22
+ def define_initialize(klass)
23
+ super_method = Dry::AutoInject.super_method(klass, :initialize)
24
+ super_params = super_method.nil? || super_method.parameters.empty? ? '' : 'options'
25
+
26
+ instance_mod.class_eval <<-RUBY, __FILE__, __LINE__ + 1
27
+ def initialize(options)
28
+ super(#{super_params})
29
+ #{dependency_map.names.map { |name| "@#{name} = options[:#{name}]" }.join("\n")}
30
+ end
31
+ RUBY
32
+ end
33
+ end
34
+
35
+ register :hash, Hash
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,68 @@
1
+ require 'dry/auto_inject/strategies/constructor'
2
+
3
+ module Dry
4
+ module AutoInject
5
+ class Strategies
6
+ # @api private
7
+ class Kwargs < Constructor
8
+ private
9
+
10
+ def define_new(_klass)
11
+ class_mod.class_eval <<-RUBY, __FILE__, __LINE__ + 1
12
+ def new(**args)
13
+ names = #{dependency_map.inspect}
14
+ deps = names.each_with_object({}) { |(name, identifier), obj|
15
+ obj[name] = args[name] || container[identifier]
16
+ }.merge(args)
17
+ super(**deps)
18
+ end
19
+ RUBY
20
+ end
21
+
22
+ def define_initialize(klass)
23
+ super_method = Dry::AutoInject.super_method(klass, :initialize)
24
+
25
+ if super_method.nil? || super_method.parameters.empty?
26
+ define_initialize_with_keywords
27
+ else
28
+ define_initialize_with_splat(super_method)
29
+ end
30
+
31
+ self
32
+ end
33
+
34
+ def define_initialize_with_keywords
35
+ initialize_params = dependency_map.names.map { |name| "#{name}: nil" }.join(', ')
36
+
37
+ instance_mod.class_eval <<-RUBY, __FILE__, __LINE__ + 1
38
+ def initialize(#{initialize_params})
39
+ super()
40
+ #{dependency_map.names.map { |name| "@#{name} = #{name}" }.join("\n")}
41
+ end
42
+ RUBY
43
+ self
44
+ end
45
+
46
+ def define_initialize_with_splat(super_method)
47
+ super_kwarg_names = super_method.parameters.select { |type, _| [:key, :keyreq].include?(type) }.map(&:last)
48
+ super_params = super_kwarg_names.map { |name| "#{name}: args[:#{name}]" }.join(', ')
49
+
50
+ # Pass through any non-dependency args if the super method accepts `**args`
51
+ if super_method.parameters.any? { |type, _| type == :keyrest }
52
+ super_params += ', **args'
53
+ end
54
+
55
+ instance_mod.class_eval <<-RUBY, __FILE__, __LINE__ + 1
56
+ def initialize(**args)
57
+ super(#{super_params})
58
+ #{dependency_map.names.map { |name| "@#{name} = args[:#{name}]" }.join("\n")}
59
+ end
60
+ RUBY
61
+ self
62
+ end
63
+ end
64
+
65
+ register_default :kwargs, Kwargs
66
+ end
67
+ end
68
+ end
@@ -1,5 +1,5 @@
1
1
  module Dry
2
- class AutoInject < Module
3
- VERSION = '0.2.0'.freeze
2
+ module AutoInject
3
+ VERSION = '0.3.0'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dry-auto_inject
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Solnica
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-02-09 00:00:00.000000000 Z
11
+ date: 2016-06-01 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: dry-container
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.3.4
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.3.4
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -73,6 +87,14 @@ files:
73
87
  - dry-auto_inject.gemspec
74
88
  - lib/dry-auto_inject.rb
75
89
  - lib/dry/auto_inject.rb
90
+ - lib/dry/auto_inject/builder.rb
91
+ - lib/dry/auto_inject/dependency_map.rb
92
+ - lib/dry/auto_inject/injector.rb
93
+ - lib/dry/auto_inject/strategies.rb
94
+ - lib/dry/auto_inject/strategies/args.rb
95
+ - lib/dry/auto_inject/strategies/constructor.rb
96
+ - lib/dry/auto_inject/strategies/hash.rb
97
+ - lib/dry/auto_inject/strategies/kwargs.rb
76
98
  - lib/dry/auto_inject/version.rb
77
99
  - rakelib/rubocop.rake
78
100
  homepage: https://github.com/dryrb/dry-auto_inject
@@ -86,7 +108,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
86
108
  requirements:
87
109
  - - ">="
88
110
  - !ruby/object:Gem::Version
89
- version: '0'
111
+ version: 2.0.0
90
112
  required_rubygems_version: !ruby/object:Gem::Requirement
91
113
  requirements:
92
114
  - - ">="
@@ -94,7 +116,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
94
116
  version: '0'
95
117
  requirements: []
96
118
  rubyforge_project:
97
- rubygems_version: 2.4.5.1
119
+ rubygems_version: 2.5.1
98
120
  signing_key:
99
121
  specification_version: 4
100
122
  summary: Container-agnostic automatic constructor injection