dry-container 0.2.1 → 0.2.2
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/.rubocop.yml +4 -0
- data/README.md +22 -3
- data/lib/dry/container.rb +4 -0
- data/lib/dry/container/mixin.rb +40 -7
- data/lib/dry/container/namespace.rb +38 -0
- data/lib/dry/container/namespace_dsl.rb +39 -0
- data/lib/dry/container/registry.rb +2 -2
- data/lib/dry/container/version.rb +1 -1
- data/spec/support/shared_examples/container.rb +105 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 00fac333cd99a672b9cb5d60dac62f5ebcb197c1
|
4
|
+
data.tar.gz: 3e040234421d7e23618d0a8fc6e5273ccdb73fb0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f161b567597ebd6f7a102ca2815687dbd1d50b4bf6d95187e4252f4793e28ef9318cf38ffd71ffdd136721ad7b65aeadde21f392e8016c538b016236c2485618
|
7
|
+
data.tar.gz: 1d6644026909c74463aa84963876d6af086ed7c6c2e8246769159298e76a8bcec1381955d2031b99fdc129e9edcc1cc05eb2784d8f5f2b0d5d4161bbc028d510
|
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
@@ -49,6 +49,25 @@ container.register(:block, call: false) do
|
|
49
49
|
end
|
50
50
|
container.resolve(:block)
|
51
51
|
# => #<Proc:0x007fa75e6830f0@(irb):36>
|
52
|
+
|
53
|
+
# You can also register items under namespaces using the #namespace method
|
54
|
+
container.namespace('repositories') do
|
55
|
+
namespace('checkout') do
|
56
|
+
register('orders') { ThreadSafe::Array.new }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
container.resolve('repositories.checkout.orders')
|
60
|
+
# => []
|
61
|
+
|
62
|
+
# Or import a namespace
|
63
|
+
ns = Dry::Container::Namespace.new('repositories') do
|
64
|
+
namespace('authentication') do
|
65
|
+
register('users') { ThreadSafe::Array.new }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
container.import(ns)
|
69
|
+
container.resolve('repositories.authentication.users')
|
70
|
+
# => []
|
52
71
|
```
|
53
72
|
|
54
73
|
You can also get container behaviour at both the class and instance level via the mixin:
|
@@ -76,7 +95,7 @@ You can configure how items are registered and resolved from the container:
|
|
76
95
|
```ruby
|
77
96
|
Dry::Container.configure do |config|
|
78
97
|
config.registry = ->(container, key, item, options) { container[key] = item }
|
79
|
-
config.resolver = ->(key) { container[key] }
|
98
|
+
config.resolver = ->(container, key) { container[key] }
|
80
99
|
end
|
81
100
|
|
82
101
|
class Container
|
@@ -84,7 +103,7 @@ class Container
|
|
84
103
|
|
85
104
|
configure do |config|
|
86
105
|
config.registry = ->(container, key, item, options) { container[key] = item }
|
87
|
-
config.resolver = ->(key) { container[key] }
|
106
|
+
config.resolver = ->(container, key) { container[key] }
|
88
107
|
end
|
89
108
|
end
|
90
109
|
|
@@ -93,7 +112,7 @@ class ContainerObject
|
|
93
112
|
|
94
113
|
configure do |config|
|
95
114
|
config.registry = ->(container, key, item, options) { container[key] = item }
|
96
|
-
config.resolver = ->(key) { container[key] }
|
115
|
+
config.resolver = ->(container, key) { container[key] }
|
97
116
|
end
|
98
117
|
end
|
99
118
|
```
|
data/lib/dry/container.rb
CHANGED
@@ -2,11 +2,15 @@ require 'thread_safe'
|
|
2
2
|
require 'dry-configurable'
|
3
3
|
require 'dry/container/error'
|
4
4
|
require 'dry/container/item'
|
5
|
+
require 'dry/container/namespace'
|
5
6
|
require 'dry/container/registry'
|
6
7
|
require 'dry/container/resolver'
|
8
|
+
require 'dry/container/namespace_dsl'
|
7
9
|
require 'dry/container/mixin'
|
8
10
|
require 'dry/container/version'
|
9
11
|
|
12
|
+
# A collection of micro-libraries, each intended to encapsulate
|
13
|
+
# a common task in Ruby
|
10
14
|
module Dry
|
11
15
|
# Inversion of Control (IoC) container
|
12
16
|
#
|
data/lib/dry/container/mixin.rb
CHANGED
@@ -31,10 +31,11 @@ module Dry
|
|
31
31
|
base.class_eval do
|
32
32
|
extend ::Dry::Configurable
|
33
33
|
|
34
|
-
setting :registry, Registry.new
|
35
|
-
setting :resolver, Resolver.new
|
34
|
+
setting :registry, ::Dry::Container::Registry.new
|
35
|
+
setting :resolver, ::Dry::Container::Resolver.new
|
36
|
+
setting :namespace_separator, '.'
|
36
37
|
|
37
|
-
@_container = ThreadSafe::Cache.new
|
38
|
+
@_container = ::ThreadSafe::Cache.new
|
38
39
|
end
|
39
40
|
end
|
40
41
|
# @private
|
@@ -42,13 +43,14 @@ module Dry
|
|
42
43
|
base.class_eval do
|
43
44
|
extend ::Dry::Configurable
|
44
45
|
|
45
|
-
setting :registry, Registry.new
|
46
|
-
setting :resolver, Resolver.new
|
46
|
+
setting :registry, ::Dry::Container::Registry.new
|
47
|
+
setting :resolver, ::Dry::Container::Resolver.new
|
48
|
+
setting :namespace_separator, '.'
|
47
49
|
|
48
50
|
attr_reader :_container
|
49
51
|
|
50
52
|
def initialize(*args, &block)
|
51
|
-
@_container = ThreadSafe::Cache.new
|
53
|
+
@_container = ::ThreadSafe::Cache.new
|
52
54
|
super(*args, &block)
|
53
55
|
end
|
54
56
|
|
@@ -69,7 +71,7 @@ module Dry
|
|
69
71
|
# If a block is given, contents will be ignored and the block
|
70
72
|
# will be registered instead
|
71
73
|
#
|
72
|
-
# @return [Dry::Container] self
|
74
|
+
# @return [Dry::Container::Mixin] self
|
73
75
|
#
|
74
76
|
# @api public
|
75
77
|
def register(key, contents = nil, options = {}, &block)
|
@@ -96,6 +98,37 @@ module Dry
|
|
96
98
|
config.resolver.call(_container, key)
|
97
99
|
end
|
98
100
|
alias_method :[], :resolve
|
101
|
+
# Evaluate block and register items in namespace
|
102
|
+
#
|
103
|
+
# @param [Mixed] namespace
|
104
|
+
# The namespace to register items in
|
105
|
+
#
|
106
|
+
# @return [Dry::Container::Mixin] self
|
107
|
+
#
|
108
|
+
# @api public
|
109
|
+
def namespace(namespace, &block)
|
110
|
+
::Dry::Container::NamespaceDSL.new(
|
111
|
+
self,
|
112
|
+
namespace,
|
113
|
+
config.namespace_separator,
|
114
|
+
&block
|
115
|
+
)
|
116
|
+
|
117
|
+
self
|
118
|
+
end
|
119
|
+
# Import a namespace
|
120
|
+
#
|
121
|
+
# @param [Dry::Container::Namespace] namespace
|
122
|
+
# The namespace to import
|
123
|
+
#
|
124
|
+
# @return [Dry::Container::Mixin] self
|
125
|
+
#
|
126
|
+
# @api public
|
127
|
+
def import(namespace)
|
128
|
+
namespace(namespace.name, &namespace.block)
|
129
|
+
|
130
|
+
self
|
131
|
+
end
|
99
132
|
end
|
100
133
|
end
|
101
134
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Dry
|
2
|
+
class Container
|
3
|
+
# Create a namespace to be imported
|
4
|
+
#
|
5
|
+
# @example
|
6
|
+
#
|
7
|
+
# ns = Dry::Container::Namespace.new('name') do
|
8
|
+
# register('item', 'item')
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# container = Dry::Container.new
|
12
|
+
#
|
13
|
+
# container.import(ns)
|
14
|
+
#
|
15
|
+
# container.resolve('name.item')
|
16
|
+
# => 'item'
|
17
|
+
#
|
18
|
+
#
|
19
|
+
# @api public
|
20
|
+
class Namespace
|
21
|
+
attr_reader :name, :block
|
22
|
+
# Create a new namespace
|
23
|
+
#
|
24
|
+
# @param [Mixed] name
|
25
|
+
# The name of the namespace
|
26
|
+
# @yield
|
27
|
+
# The block to evaluate when the namespace is imported
|
28
|
+
#
|
29
|
+
# @return [Dry::Container::Namespace]
|
30
|
+
#
|
31
|
+
# @api public
|
32
|
+
def initialize(name, &block)
|
33
|
+
@name = name
|
34
|
+
@block = block
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Dry
|
2
|
+
class Container
|
3
|
+
# @api private
|
4
|
+
class NamespaceDSL < ::SimpleDelegator
|
5
|
+
def initialize(container, namespace, namespace_separator, &block)
|
6
|
+
@namespace = namespace
|
7
|
+
@namespace_separator = namespace_separator
|
8
|
+
|
9
|
+
super(container)
|
10
|
+
|
11
|
+
if block.arity.zero?
|
12
|
+
instance_eval(&block)
|
13
|
+
else
|
14
|
+
block.call(self)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def register(key, *args, &block)
|
19
|
+
super(namespaced(key), *args, &block)
|
20
|
+
end
|
21
|
+
|
22
|
+
def namespace(namespace, &block)
|
23
|
+
super(namespaced(namespace), &block)
|
24
|
+
end
|
25
|
+
|
26
|
+
def import(namespace)
|
27
|
+
namespace(namespace.name, &namespace.block)
|
28
|
+
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def namespaced(key)
|
35
|
+
[@namespace, key].join(@namespace_separator)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -6,7 +6,7 @@ module Dry
|
|
6
6
|
class Registry
|
7
7
|
# @private
|
8
8
|
def initialize
|
9
|
-
@_mutex = Mutex.new
|
9
|
+
@_mutex = ::Mutex.new
|
10
10
|
end
|
11
11
|
# Register an item with the container to be resolved later
|
12
12
|
#
|
@@ -31,7 +31,7 @@ module Dry
|
|
31
31
|
if container.key?(key)
|
32
32
|
fail Error, "There is already an item registered with the key #{key.inspect}"
|
33
33
|
else
|
34
|
-
container[key] = Item.new(item, options)
|
34
|
+
container[key] = ::Dry::Container::Item.new(item, options)
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
@@ -72,6 +72,41 @@ shared_examples 'a container' do
|
|
72
72
|
it { is_expected.to eq(item) }
|
73
73
|
end
|
74
74
|
end
|
75
|
+
|
76
|
+
describe 'namespace_separator' do
|
77
|
+
describe 'default' do
|
78
|
+
it { expect(klass.config.namespace_separator).to eq('.') }
|
79
|
+
end
|
80
|
+
|
81
|
+
describe 'custom' do
|
82
|
+
let(:custom_registry) { double('Registry') }
|
83
|
+
let(:key) { 'key' }
|
84
|
+
let(:namespace_separator) { '-' }
|
85
|
+
let(:namespace) { 'one' }
|
86
|
+
|
87
|
+
before do
|
88
|
+
klass.configure do |config|
|
89
|
+
config.namespace_separator = namespace_separator
|
90
|
+
end
|
91
|
+
|
92
|
+
container.namespace(namespace) do
|
93
|
+
register('key', 'item')
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
after do
|
98
|
+
# HACK: Have to reset the configuration so that it doesn't
|
99
|
+
# interfere with other specs
|
100
|
+
klass.configure do |config|
|
101
|
+
config.namespace_separator = '.'
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
subject! { container.resolve([namespace, key].join(namespace_separator)) }
|
106
|
+
|
107
|
+
it { is_expected.to eq('item') }
|
108
|
+
end
|
109
|
+
end
|
75
110
|
end
|
76
111
|
|
77
112
|
context 'with default configuration' do
|
@@ -149,5 +184,75 @@ shared_examples 'a container' do
|
|
149
184
|
expect { container.resolve(:item) }.to raise_error(Dry::Container::Error)
|
150
185
|
end
|
151
186
|
end
|
187
|
+
|
188
|
+
describe 'namespace' do
|
189
|
+
context 'when block does not take arguments' do
|
190
|
+
before do
|
191
|
+
container.namespace('one') do
|
192
|
+
register('two', 2)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
subject! { container.resolve('one.two') }
|
197
|
+
|
198
|
+
it 'registers items under the given namespace' do
|
199
|
+
is_expected.to eq(2)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
context 'when block takes arguments' do
|
204
|
+
before do
|
205
|
+
container.namespace('one') do |c|
|
206
|
+
c.register('two', 2)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
subject! { container.resolve('one.two') }
|
211
|
+
|
212
|
+
it 'registers items under the given namespace' do
|
213
|
+
is_expected.to eq(2)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
context 'with nesting' do
|
218
|
+
before do
|
219
|
+
container.namespace('one') do
|
220
|
+
namespace('two') do
|
221
|
+
register('three', 3)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
subject! { container.resolve('one.two.three') }
|
227
|
+
|
228
|
+
it 'registers items under the given namespaces' do
|
229
|
+
is_expected.to eq(3)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
describe 'import' do
|
235
|
+
it 'allows importing of namespaces' do
|
236
|
+
ns = Dry::Container::Namespace.new('one') do
|
237
|
+
register('two', 2)
|
238
|
+
end
|
239
|
+
|
240
|
+
container.import(ns)
|
241
|
+
|
242
|
+
expect(container.resolve('one.two')).to eq(2)
|
243
|
+
end
|
244
|
+
|
245
|
+
it 'allows importing of nested namespaces' do
|
246
|
+
ns = Dry::Container::Namespace.new('two') do
|
247
|
+
register('three', 3)
|
248
|
+
end
|
249
|
+
|
250
|
+
container.namespace('one') do
|
251
|
+
import(ns)
|
252
|
+
end
|
253
|
+
|
254
|
+
expect(container.resolve('one.two.three')).to eq(3)
|
255
|
+
end
|
256
|
+
end
|
152
257
|
end
|
153
258
|
end
|
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.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Holland
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-08-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thread_safe
|
@@ -102,6 +102,8 @@ files:
|
|
102
102
|
- lib/dry/container/error.rb
|
103
103
|
- lib/dry/container/item.rb
|
104
104
|
- lib/dry/container/mixin.rb
|
105
|
+
- lib/dry/container/namespace.rb
|
106
|
+
- lib/dry/container/namespace_dsl.rb
|
105
107
|
- lib/dry/container/registry.rb
|
106
108
|
- lib/dry/container/resolver.rb
|
107
109
|
- lib/dry/container/version.rb
|