dry-container 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +23 -0
- data/dry-container.gemspec +2 -0
- data/lib/dry/container/item.rb +20 -1
- data/lib/dry/container/mixin.rb +14 -6
- data/lib/dry/container/registry.rb +1 -1
- data/lib/dry/container/version.rb +1 -1
- data/spec/support/shared_examples/container.rb +27 -0
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2f11ec3380a6ff086362780a67b687935cff8ddf
|
4
|
+
data.tar.gz: 15db84953170fdc3f249d852d01d106f7a904f23
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f36ffd98d0c80ffd158e1554a09dd89919aeb7c780010a276118ad217db89d9ace865746c18b97321b6022d75dc5a4e46523d27927cd01ee182d0bb3b6b105b8
|
7
|
+
data.tar.gz: 7b52ee74e85b40edad15d082ad5fc64a20a00947a8d97d472be013f4f98fe363be5c25f007cd6d089582d0302034b35ed0041ce843e276c896100a9775a2a14a
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
## v0.5.0
|
2
|
+
|
3
|
+
## Added
|
4
|
+
|
5
|
+
* `memoize` option to `#register` - memoizes items on first resolve ([ivoanjo](https://github.com/ivoanjo))
|
6
|
+
|
7
|
+
## Fixed
|
8
|
+
|
9
|
+
* `required_ruby_version` set to `>= 2.0.0` ([artofhuman](https://github.com/artofhuman))
|
10
|
+
|
11
|
+
[Compare v0.4.0...HEAD](https://github.com/dry-rb/dry-container/compare/v0.4.0...HEAD)
|
data/README.md
CHANGED
@@ -91,6 +91,29 @@ end
|
|
91
91
|
container.import(ns)
|
92
92
|
container.resolve('repositories.authentication.users')
|
93
93
|
# => []
|
94
|
+
|
95
|
+
# You can also register a block that is used to initialize a dependency and
|
96
|
+
# then memoize it, allowing several dependencies to be added without
|
97
|
+
# enforcing an instantiation order
|
98
|
+
class MessagePrinter
|
99
|
+
def initialize(container)
|
100
|
+
@message = container.resolve(:message)
|
101
|
+
@time = Time.now
|
102
|
+
end
|
103
|
+
|
104
|
+
def print
|
105
|
+
puts "#{@message} at #{@time}"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
container.register(:message_printer, -> { MessagePrinter.new(container) }, memoize: true)
|
110
|
+
container.register(:message, 'Hello, world!')
|
111
|
+
container.resolve(:message_printer).print
|
112
|
+
# => Hello, world! at 2016-08-30 05:32:12 -0700
|
113
|
+
|
114
|
+
# Same instance is reused next time
|
115
|
+
container.resolve(:message_printer).print
|
116
|
+
# => Hello, world! at 2016-08-30 05:32:12 -0700
|
94
117
|
```
|
95
118
|
|
96
119
|
You can also get container behaviour at both the class and instance level via the mixin:
|
data/dry-container.gemspec
CHANGED
@@ -15,6 +15,8 @@ Gem::Specification.new do |spec|
|
|
15
15
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
16
16
|
spec.require_paths = ['lib']
|
17
17
|
|
18
|
+
spec.required_ruby_version = ">= 2.0.0"
|
19
|
+
|
18
20
|
spec.add_runtime_dependency 'concurrent-ruby', '~> 1.0'
|
19
21
|
spec.add_runtime_dependency 'dry-configurable', '~> 0.1', '>= 0.1.3'
|
20
22
|
|
data/lib/dry/container/item.rb
CHANGED
@@ -4,22 +4,41 @@ module Dry
|
|
4
4
|
#
|
5
5
|
# @private
|
6
6
|
class Item
|
7
|
-
attr_reader :item, :options
|
7
|
+
attr_reader :item, :options, :memoize, :memoize_mutex
|
8
8
|
|
9
9
|
def initialize(item, options = {})
|
10
10
|
@item = item
|
11
11
|
@options = {
|
12
12
|
call: item.is_a?(::Proc) && item.parameters.empty?
|
13
13
|
}.merge(options)
|
14
|
+
|
15
|
+
if options[:memoize] == true
|
16
|
+
raise(
|
17
|
+
::Dry::Container::Error,
|
18
|
+
'Memoize only supported for a block or a proc'
|
19
|
+
) unless item.is_a?(::Proc)
|
20
|
+
@memoize = true
|
21
|
+
@memoize_mutex = ::Mutex.new
|
22
|
+
end
|
14
23
|
end
|
15
24
|
|
16
25
|
def call
|
26
|
+
return memoized_item if memoize
|
27
|
+
|
17
28
|
if options[:call] == true
|
18
29
|
item.call
|
19
30
|
else
|
20
31
|
item
|
21
32
|
end
|
22
33
|
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def memoized_item
|
38
|
+
memoize_mutex.synchronize do
|
39
|
+
@memoized_item ||= item.call
|
40
|
+
end
|
41
|
+
end
|
23
42
|
end
|
24
43
|
end
|
25
44
|
end
|
data/lib/dry/container/mixin.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Dry
|
2
2
|
class Container
|
3
3
|
PREFIX_NAMESPACE = ->(namespace, key, config) do
|
4
|
-
[namespace, key].
|
4
|
+
[namespace, key].join(config.namespace_separator)
|
5
5
|
end
|
6
6
|
# Mixin to expose Inversion of Control (IoC) container behaviour
|
7
7
|
#
|
@@ -125,16 +125,24 @@ module Dry
|
|
125
125
|
#
|
126
126
|
# @param [Dry::Container] other
|
127
127
|
# The other container to merge in
|
128
|
+
# @param [Hash] options
|
129
|
+
# @option options [Symbol] :namespace
|
130
|
+
# Namespace to prefix other container items with, defaults to nil
|
128
131
|
#
|
129
132
|
# @return [Dry::Container::Mixin] self
|
130
133
|
#
|
131
134
|
# @api public
|
132
135
|
def merge(other, namespace: nil)
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
136
|
+
if namespace
|
137
|
+
_container.merge!(
|
138
|
+
other._container.each_with_object(::Concurrent::Hash.new) do |a, h|
|
139
|
+
h[PREFIX_NAMESPACE.call(namespace, a.first, config)] = a.last
|
140
|
+
end
|
141
|
+
)
|
142
|
+
else
|
143
|
+
_container.merge!(other._container)
|
144
|
+
end
|
145
|
+
|
138
146
|
self
|
139
147
|
end
|
140
148
|
|
@@ -185,6 +185,33 @@ shared_examples 'a container' do
|
|
185
185
|
expect(container[:item].call).to eq('item')
|
186
186
|
end
|
187
187
|
end
|
188
|
+
|
189
|
+
context 'with option memoize: true' do
|
190
|
+
it 'registers and resolves a proc' do
|
191
|
+
container.register(:item, proc { 'item' }, memoize: true)
|
192
|
+
|
193
|
+
expect(container[:item]).to be container[:item]
|
194
|
+
expect(container.keys).to eq(['item'])
|
195
|
+
expect(container.key?(:item)).to be true
|
196
|
+
expect(container.resolve(:item)).to eq('item')
|
197
|
+
expect(container[:item]).to eq('item')
|
198
|
+
end
|
199
|
+
|
200
|
+
it 'only resolves the proc once' do
|
201
|
+
resolved_times = 0
|
202
|
+
|
203
|
+
container.register(:item, proc { resolved_times += 1 }, memoize: true)
|
204
|
+
|
205
|
+
expect(container.resolve(:item)).to be 1
|
206
|
+
expect(container.resolve(:item)).to be 1
|
207
|
+
end
|
208
|
+
|
209
|
+
context 'when receiving something other than a proc' do
|
210
|
+
it do
|
211
|
+
expect { container.register(:item, 'Hello!', memoize: true) }.to raise_error(Dry::Container::Error)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
188
215
|
end
|
189
216
|
|
190
217
|
describe 'registering an object' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dry-container
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Holland
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-08-
|
11
|
+
date: 2016-08-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -99,6 +99,7 @@ files:
|
|
99
99
|
- ".rubocop.yml"
|
100
100
|
- ".rubocop_todo.yml"
|
101
101
|
- ".travis.yml"
|
102
|
+
- CHANGELOG.md
|
102
103
|
- Gemfile
|
103
104
|
- LICENSE
|
104
105
|
- README.md
|
@@ -132,7 +133,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
132
133
|
requirements:
|
133
134
|
- - ">="
|
134
135
|
- !ruby/object:Gem::Version
|
135
|
-
version:
|
136
|
+
version: 2.0.0
|
136
137
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
137
138
|
requirements:
|
138
139
|
- - ">="
|
@@ -149,4 +150,3 @@ test_files:
|
|
149
150
|
- spec/integration/mixin_spec.rb
|
150
151
|
- spec/spec_helper.rb
|
151
152
|
- spec/support/shared_examples/container.rb
|
152
|
-
has_rdoc:
|