diftw 1.0.0.pre.rc1 → 1.0.0.pre.rc2
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/README.md +18 -15
- data/lib/diftw.rb +2 -1
- data/lib/diftw/factory.rb +23 -0
- data/lib/diftw/injector.rb +23 -22
- data/lib/diftw/singleton.rb +25 -0
- data/lib/diftw/version.rb +1 -1
- metadata +4 -3
- data/lib/diftw/dependency.rb +0 -38
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2fdc140e5795f103a584d7a7799acd59e40000e3
|
4
|
+
data.tar.gz: 03e40f06fb27bc8e20ecdc03711bb8043dc75de6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ec92e112aec09c21bcafe39a73a8b9aa623aa2917a26ca730e4047d68a5d8c4fbd0ef8061e0f59290931ec07cc287ab102e5a391ffd0daccce9b51fdfe98ae2a
|
7
|
+
data.tar.gz: c3e1f46d4b45018dbcf5289acba1362e5f54f2a4d0f83c06de8dd099cbcedb5f1bca42905c2cb363820d5de5eedc28e61ff6e1d2dbac0ad8ce210505f33b97c6
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# DiFtw
|
1
|
+
# DiFtw [](https://travis-ci.org/jhollinger/ruby-diftw)
|
2
2
|
|
3
3
|
Dependency Injection For The Win! A small, yet surprisingly powerful, dependency injection library for Ruby.
|
4
4
|
|
@@ -11,27 +11,30 @@ If your only concern is testing, mocks/stubs and `webmock` might be all you need
|
|
11
11
|
* DI container w/dead-simple registration
|
12
12
|
* Lazy injection (by default)
|
13
13
|
* Inject into each of a class's instances, a single instance, a class itself, or a module
|
14
|
-
*
|
14
|
+
* Inject singletons or factories
|
15
15
|
* Uses parent-child injectors for max flexibility
|
16
|
-
* Threadsafe,
|
16
|
+
* Threadsafe, after registration
|
17
17
|
|
18
18
|
## Dead-simple registration API
|
19
19
|
|
20
20
|
# Create your root injector/container
|
21
21
|
DI = DiFtw::Injector.new do
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
singleton :foo do
|
23
|
+
OpenStruct.new(message: "Everyone will get this same object")
|
24
|
+
end
|
25
|
+
|
26
|
+
factory :bar do
|
27
|
+
OpenStruct.new(message: "Everyone will get a NEW version of this object")
|
25
28
|
end
|
26
29
|
end
|
27
30
|
|
28
|
-
# Or register
|
29
|
-
DI.
|
31
|
+
# Or register things out here
|
32
|
+
DI.singleton :zorp do
|
30
33
|
OpenStruct.new(message: "Bar")
|
31
34
|
end
|
32
35
|
|
33
|
-
# Or
|
34
|
-
DI
|
36
|
+
# Or use a Proc
|
37
|
+
DI.factory :xyz, -> { OpenStruct.new(message: "XYZ") }
|
35
38
|
|
36
39
|
## Lazy injection (by default)
|
37
40
|
|
@@ -107,7 +110,7 @@ This means you can re-register a dependency on a child injector, and *it* will b
|
|
107
110
|
|
108
111
|
# Create your root injector and register :foo
|
109
112
|
DI = DiFtw::Injector.new
|
110
|
-
DI
|
113
|
+
DI.singleton :foo, -> { 'Foo' }
|
111
114
|
|
112
115
|
class Widget
|
113
116
|
include DI.inject :foo
|
@@ -143,7 +146,7 @@ This means you can re-register a dependency on a child injector, and *it* will b
|
|
143
146
|
|
144
147
|
# But we could re-register/override :foo in Spline.injector, and all new
|
145
148
|
# Spline instances would resolve :foo differently.
|
146
|
-
Spline.injector
|
149
|
+
Spline.injector.singleton :foo, -> { 'Bar' }
|
147
150
|
Spline.new.foo
|
148
151
|
=> 'Bar'
|
149
152
|
# But DI and Widget.injector would be unchanged
|
@@ -153,7 +156,7 @@ This means you can re-register a dependency on a child injector, and *it* will b
|
|
153
156
|
# We can go even further and override :foo in just one specific instance of Spline
|
154
157
|
# NOTE This only works if you're using lazy injection (the default) AND if you haven't called #foo yet
|
155
158
|
s = Spline.new
|
156
|
-
s.injector
|
159
|
+
s.injector.singleton :foo, -> { 'Baz' }
|
157
160
|
s.foo
|
158
161
|
=> 'Baz'
|
159
162
|
# Other Spline instances will still get their override from Spline.injector
|
@@ -167,13 +170,13 @@ This means you can re-register a dependency on a child injector, and *it* will b
|
|
167
170
|
|
168
171
|
To inject different dependencies in these environments, you have several options. You can simply re-register dependencies in your root injector:
|
169
172
|
|
170
|
-
DI
|
173
|
+
DI.singleton :foo, -> { OpenStruct.new(message: 'Test Foo') }
|
171
174
|
|
172
175
|
And/Or you can use the parent-child injector features described above to great effect:
|
173
176
|
|
174
177
|
before :each do
|
175
178
|
# Give all MyService instances 'Test foo' as #foo
|
176
|
-
MyService.injector
|
179
|
+
MyService.injector.singleton :foo, -> {
|
177
180
|
'Test foo'
|
178
181
|
}
|
179
182
|
end
|
data/lib/diftw.rb
CHANGED
@@ -0,0 +1,23 @@
|
|
1
|
+
module DiFtw
|
2
|
+
#
|
3
|
+
# A dependency that will be re-created every time it's injected.
|
4
|
+
#
|
5
|
+
class Factory
|
6
|
+
#
|
7
|
+
# A new dependency.
|
8
|
+
#
|
9
|
+
# @param y [Proc] returns the dependency
|
10
|
+
#
|
11
|
+
def initialize(y)
|
12
|
+
@y = y
|
13
|
+
@val = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
#
|
17
|
+
# Return the value for the dependency by calling the registration Proc.
|
18
|
+
#
|
19
|
+
def resolve
|
20
|
+
@y.()
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/diftw/injector.rb
CHANGED
@@ -8,21 +8,21 @@ module DiFtw
|
|
8
8
|
# DI = DiFtw::Injector.new
|
9
9
|
#
|
10
10
|
# # You can call register on the Injector object
|
11
|
-
# DI.
|
11
|
+
# DI.singleton :bar do
|
12
12
|
# Bar.new
|
13
13
|
# end
|
14
14
|
#
|
15
|
-
# # Or you can
|
16
|
-
# DI
|
15
|
+
# # Or you can pass a Proc
|
16
|
+
# DI.singleton :baz, -> { Baz.new }
|
17
17
|
#
|
18
18
|
# Alternatively, you can pass a block to the initializer and register your depencies right inside it:
|
19
19
|
#
|
20
20
|
# DI = DiFtw::Injector.new do
|
21
|
-
#
|
21
|
+
# singleton :foo do
|
22
22
|
# Foo.new
|
23
23
|
# end
|
24
24
|
#
|
25
|
-
#
|
25
|
+
# singleton :bar, -> { Bar }
|
26
26
|
# end
|
27
27
|
#
|
28
28
|
class Injector
|
@@ -41,44 +41,45 @@ module DiFtw
|
|
41
41
|
#
|
42
42
|
def initialize(parent: nil, ®istrator)
|
43
43
|
@registry, @parent = {}, parent
|
44
|
-
instance_eval
|
44
|
+
instance_eval(®istrator) if registrator
|
45
45
|
end
|
46
46
|
|
47
47
|
#
|
48
|
-
# Register a new dependency
|
49
|
-
#
|
50
|
-
#
|
48
|
+
# Register a new dependency as a singleton. The proc will only be called
|
49
|
+
# the first time, then the returned value will be stored and returned for
|
50
|
+
# subsequent injections. Threadsafe.
|
51
|
+
#
|
52
|
+
# DI.singleton :foo do
|
51
53
|
# Foo
|
52
54
|
# end
|
53
55
|
#
|
54
|
-
# DI.
|
56
|
+
# DI.singleton :bar, -> { Bar }
|
55
57
|
#
|
56
58
|
# @param name [Symbol] name of the dependency
|
57
59
|
# @param y [Proc] the dependency wrapped in a Proc or block
|
58
60
|
# @return [DiFtw::Injector] returns the Injector object
|
59
|
-
#
|
60
|
-
def
|
61
|
-
registry[name] =
|
61
|
+
#
|
62
|
+
def singleton(name, y = nil, &block)
|
63
|
+
registry[name] = Singleton.new(y || block)
|
62
64
|
self
|
63
65
|
end
|
64
66
|
|
65
67
|
#
|
66
|
-
# Register a new dependency
|
67
|
-
#
|
68
|
-
#
|
69
|
-
#
|
70
|
-
# DI.singleton :foo do
|
68
|
+
# Register a new dependency by passing a Proc or a block. Each time you
|
69
|
+
# inject it, the block/Proc will be re-run and you'll get the result.
|
70
|
+
#
|
71
|
+
# DI.factory :foo do
|
71
72
|
# Foo
|
72
73
|
# end
|
73
74
|
#
|
74
|
-
# DI.
|
75
|
+
# DI.factory :bar, -> { Bar }
|
75
76
|
#
|
76
77
|
# @param name [Symbol] name of the dependency
|
77
78
|
# @param y [Proc] the dependency wrapped in a Proc or block
|
78
79
|
# @return [DiFtw::Injector] returns the Injector object
|
79
|
-
#
|
80
|
-
def
|
81
|
-
registry[name] =
|
80
|
+
#
|
81
|
+
def factory(name, y = nil, &block)
|
82
|
+
registry[name] = Factory.new(y || block)
|
82
83
|
self
|
83
84
|
end
|
84
85
|
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module DiFtw
|
2
|
+
#
|
3
|
+
# Class representing an injected dependency that's only created once.
|
4
|
+
#
|
5
|
+
class Singleton
|
6
|
+
#
|
7
|
+
# A new dependency.
|
8
|
+
#
|
9
|
+
# @param y [Proc] returns the dependency
|
10
|
+
#
|
11
|
+
def initialize(y)
|
12
|
+
@y = y
|
13
|
+
@val = nil
|
14
|
+
@mutex = Mutex.new
|
15
|
+
end
|
16
|
+
|
17
|
+
#
|
18
|
+
# Return the value for the dependency. If this is the first access, the injected value
|
19
|
+
# will be cached and re-used for later injections. Yes, it's thread-safe.
|
20
|
+
#
|
21
|
+
def resolve
|
22
|
+
@val || @mutex.synchronize { @val ||= @y.() }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/diftw/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: diftw
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.pre.
|
4
|
+
version: 1.0.0.pre.rc2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jordan Hollinger
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-09-09 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A small dependency injection library for Ruby
|
14
14
|
email: jordan.hollinger@gmail.com
|
@@ -20,8 +20,9 @@ files:
|
|
20
20
|
- README.md
|
21
21
|
- lib/diftw.rb
|
22
22
|
- lib/diftw/builder.rb
|
23
|
-
- lib/diftw/
|
23
|
+
- lib/diftw/factory.rb
|
24
24
|
- lib/diftw/injector.rb
|
25
|
+
- lib/diftw/singleton.rb
|
25
26
|
- lib/diftw/version.rb
|
26
27
|
homepage: https://github.com/jhollinger/ruby-diftw
|
27
28
|
licenses:
|
data/lib/diftw/dependency.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
module DiFtw
|
2
|
-
#
|
3
|
-
# Class representing an injected dependency.
|
4
|
-
#
|
5
|
-
class Dependency
|
6
|
-
# @return [Proc] proc that returns the dependency
|
7
|
-
attr_reader :y
|
8
|
-
# @return [Boolean] whether or not this depdency is a singleton
|
9
|
-
attr_reader :singleton
|
10
|
-
# @return [Mutex] the mutex for accessing the Singleton
|
11
|
-
attr_reader :mutex
|
12
|
-
|
13
|
-
#
|
14
|
-
# A new dependency.
|
15
|
-
#
|
16
|
-
# @param y [Proc] returns the dependency
|
17
|
-
# @param singleton [Boolean] if true, the Proc will only be called the first time the dep is injected.
|
18
|
-
#
|
19
|
-
def initialize(y, singleton:)
|
20
|
-
@y = y
|
21
|
-
@singleton = singleton
|
22
|
-
@mutex = Mutex.new if singleton
|
23
|
-
end
|
24
|
-
|
25
|
-
#
|
26
|
-
# Return the value for the dependency. If this is a singleton, the value will
|
27
|
-
# only be initialized on the first call (thread safe). Otherwise, the proc will
|
28
|
-
# called each time.
|
29
|
-
#
|
30
|
-
def resolve
|
31
|
-
if singleton
|
32
|
-
@val || mutex.synchronize { @val ||= y.() }
|
33
|
-
else
|
34
|
-
y.()
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|