smart_injection 0.0.0.alpha2 → 0.0.0.alpha3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +3 -3
- data/README.md +6 -6
- data/lib/smart_core/injection/injector/container_set.rb +27 -0
- data/lib/smart_core/injection/injector/container_set/adding_listener.rb +30 -0
- data/lib/smart_core/injection/locator.rb +1 -1
- data/lib/smart_core/injection/locator/container_proxy.rb +66 -4
- data/lib/smart_core/injection/locator/dependency.rb +2 -2
- data/lib/smart_core/injection/locator/factory.rb +6 -4
- data/lib/smart_core/injection/version.rb +1 -1
- data/smart_injection.gemspec +1 -1
- metadata +11 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d6f87bba0170853c09fc72fd200054365cc4653d76bf7c3e2347af9d5c8a3e59
|
4
|
+
data.tar.gz: 9f09cbfca987d5a0423f8ff0100d4c1a2732b1f9051ec689fa8106dc5bde2678
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: de681417379858196fad5b211b065e226c1744c20472d592b479697ff82a309ba111b9a460c5b4484ca81499c486848bfa445567c95ba32100b0d1112def7cd1
|
7
|
+
data.tar.gz: 15d6cfd72927a2d46c9d71465b1650666cb81f5bc112d1abb3710ff4f397718b49debb4a1c821259e118ffeb09d34b8173c1b4e4359d4342018ed46db20f3f27
|
data/Gemfile.lock
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
smart_injection (0.0.0.
|
5
|
-
smart_container (~> 0.
|
4
|
+
smart_injection (0.0.0.alpha2)
|
5
|
+
smart_container (~> 0.8, >= 0.8.1)
|
6
6
|
smart_engine (~> 0.7)
|
7
7
|
|
8
8
|
GEM
|
@@ -79,7 +79,7 @@ GEM
|
|
79
79
|
docile (~> 1.1)
|
80
80
|
simplecov-html (~> 0.11)
|
81
81
|
simplecov-html (0.12.2)
|
82
|
-
smart_container (0.
|
82
|
+
smart_container (0.8.1)
|
83
83
|
smart_engine (~> 0.5)
|
84
84
|
smart_engine (0.7.0)
|
85
85
|
thread_safe (0.3.6)
|
data/README.md
CHANGED
@@ -8,7 +8,7 @@ Dependency injection principles and idioms realized in scope of Ruby.
|
|
8
8
|
|
9
9
|
- `method-injection` strategy
|
10
10
|
- `soon:` constructor injection strategy;
|
11
|
-
- `soon:`
|
11
|
+
- `soon:` property injection strategy;
|
12
12
|
- realized as a mixin;
|
13
13
|
- instance-method dependency injection;
|
14
14
|
- class-method dependency injection;
|
@@ -80,18 +80,18 @@ class MiniService
|
|
80
80
|
include SmartCore::Injection(AppContainer, ServiceContainer)
|
81
81
|
|
82
82
|
# --- or ---
|
83
|
-
include SmartCore::
|
83
|
+
include SmartCore::Injection
|
84
84
|
register_container(AppContainer, ServiceContainer)
|
85
85
|
|
86
86
|
# import dependencies to an instance
|
87
|
-
import
|
88
|
-
import
|
87
|
+
import({ db: 'data_storage.main' }, bind: :dynamic, access: :private)
|
88
|
+
import({ rnd: 'rands.alphanum' }, bind: :static, memoize: true)
|
89
89
|
|
90
90
|
# import dependencies to a class
|
91
|
-
import_static
|
91
|
+
import_static({ cache: 'data_storage.cache', hexer: 'rands.hex' }, bind: :static)
|
92
92
|
|
93
93
|
# import from a non-registered container
|
94
|
-
import
|
94
|
+
import({ phone_client: 'phone_clients.nexmo' }, from: GlobalContainer)
|
95
95
|
|
96
96
|
def call
|
97
97
|
db # => returns data_storage.main
|
@@ -3,6 +3,8 @@
|
|
3
3
|
# @api private
|
4
4
|
# @since 0.1.0
|
5
5
|
class SmartCore::Injection::Injector::ContainerSet
|
6
|
+
require_relative 'container_set/adding_listener'
|
7
|
+
|
6
8
|
# @since 0.1.0
|
7
9
|
include Enumerable
|
8
10
|
|
@@ -12,6 +14,7 @@ class SmartCore::Injection::Injector::ContainerSet
|
|
12
14
|
# @since 0.1.0
|
13
15
|
def initialize
|
14
16
|
@containers = [] # NOTE: we use Array cuz we need an ordered set
|
17
|
+
@adding_listeners = []
|
15
18
|
@access_lock = SmartCore::Engine::Lock.new
|
16
19
|
end
|
17
20
|
|
@@ -25,6 +28,17 @@ class SmartCore::Injection::Injector::ContainerSet
|
|
25
28
|
end
|
26
29
|
alias_method :<<, :add
|
27
30
|
|
31
|
+
# @param listener [Block]
|
32
|
+
# @yield [container]
|
33
|
+
# @yieldparam container [SmartCore::Container]
|
34
|
+
# @return [void]
|
35
|
+
#
|
36
|
+
# @api private
|
37
|
+
# @since 0.1.0
|
38
|
+
def listen_addings(&listener)
|
39
|
+
thread_safe { add_adding_listener(listener) }
|
40
|
+
end
|
41
|
+
|
28
42
|
# @param block [Block]
|
29
43
|
# @yield [container]
|
30
44
|
# @yieldparam container [SmartCore::Container]
|
@@ -63,6 +77,18 @@ class SmartCore::Injection::Injector::ContainerSet
|
|
63
77
|
# @since 0.1.0
|
64
78
|
attr_reader :containers
|
65
79
|
|
80
|
+
# @return [Array<SmartCore::Injection::Injector::ContainerSet::AddingListener>]
|
81
|
+
attr_reader :adding_listeners
|
82
|
+
|
83
|
+
# @param listener [Proc]
|
84
|
+
# @return [void]
|
85
|
+
#
|
86
|
+
# @api private
|
87
|
+
# @since 0.1.0
|
88
|
+
def add_adding_listener(listener)
|
89
|
+
adding_listeners << SmartCore::Injection::Injector::ContainerSet::AddingListener.new(listener)
|
90
|
+
end
|
91
|
+
|
66
92
|
# @param container [SmartCore::Container]
|
67
93
|
# @return [void]
|
68
94
|
#
|
@@ -73,6 +99,7 @@ class SmartCore::Injection::Injector::ContainerSet
|
|
73
99
|
# - #concant is used to prevent container duplications in ordered set;
|
74
100
|
# - @containers should have an ordered unified container list;
|
75
101
|
containers.concat([container])
|
102
|
+
adding_listeners.each { |listener| listener.notify(container) }
|
76
103
|
end
|
77
104
|
|
78
105
|
# @param block [Block]
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.1.0
|
5
|
+
class SmartCore::Injection::Injector::ContainerSet::AddingListener
|
6
|
+
# @param listener [Proc]
|
7
|
+
# @return [void]
|
8
|
+
#
|
9
|
+
# @api private
|
10
|
+
# @since 0.1.0
|
11
|
+
def initialize(listener)
|
12
|
+
@listener = listener
|
13
|
+
end
|
14
|
+
|
15
|
+
# @param cotnainer [SmartCore::Container]
|
16
|
+
#
|
17
|
+
# @api private
|
18
|
+
# @since 0.1.0
|
19
|
+
def notify(container)
|
20
|
+
listener.call(container)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
# @return [Proc]
|
26
|
+
#
|
27
|
+
# @api private
|
28
|
+
# @since 0.1.0
|
29
|
+
attr_reader :listener
|
30
|
+
end
|
@@ -39,7 +39,7 @@ class SmartCore::Injection::Locator
|
|
39
39
|
# @api private
|
40
40
|
# @since 0.1.0
|
41
41
|
def rebind_dependency
|
42
|
-
dependency.rebind { container_proxy.
|
42
|
+
dependency.rebind { container_proxy.resolve_dependency(import_path) }
|
43
43
|
end
|
44
44
|
alias_method :rebind!, :rebind_dependency
|
45
45
|
|
@@ -12,6 +12,8 @@ class SmartCore::Injection::Locator::ContainerProxy
|
|
12
12
|
def initialize(registered_containers, explicitly_passed_container)
|
13
13
|
@registered_containers = registered_containers
|
14
14
|
@explicitly_passed_container = explicitly_passed_container
|
15
|
+
@observers = Hash.new { |h, k| h[k] = [] }
|
16
|
+
registered_containers.listen_addings { |container| listen_changes(container) }
|
15
17
|
end
|
16
18
|
|
17
19
|
# @param dependency_path [String]
|
@@ -49,11 +51,21 @@ class SmartCore::Injection::Locator::ContainerProxy
|
|
49
51
|
# @api private
|
50
52
|
# @since 0.1.0
|
51
53
|
def observe(import_path, &observer)
|
52
|
-
|
54
|
+
register_observer(import_path, observer)
|
55
|
+
|
56
|
+
each_container do |container|
|
57
|
+
container.observe(import_path) { |path, cntr| process_changement(cntr, path) }
|
58
|
+
end
|
53
59
|
end
|
54
60
|
|
55
61
|
private
|
56
62
|
|
63
|
+
# @return [Hash<String,Proc>]
|
64
|
+
#
|
65
|
+
# @api private
|
66
|
+
# @since 0.1.0
|
67
|
+
attr_reader :observers
|
68
|
+
|
57
69
|
# @return [SmartCore::Injection::Injector::ContainerSet]
|
58
70
|
#
|
59
71
|
# @api private
|
@@ -66,15 +78,65 @@ class SmartCore::Injection::Locator::ContainerProxy
|
|
66
78
|
# @since 0.1.0
|
67
79
|
attr_reader :explicitly_passed_container
|
68
80
|
|
81
|
+
# @param import_path [NilClass, String]
|
82
|
+
# @param container [SmartCore::Container]
|
83
|
+
# @return [void]
|
84
|
+
#
|
85
|
+
# @api private
|
86
|
+
# @since 0.1.0
|
87
|
+
def process_changement(container, import_path = nil)
|
88
|
+
observed_pathes = import_path ? [import_path] : observed_import_pathes
|
89
|
+
|
90
|
+
observed_pathes.each do |observed_path|
|
91
|
+
suitable_container = each_container.find { |cntr| cntr.key?(observed_path) }
|
92
|
+
break unless suitable_container
|
93
|
+
notify_observers(observed_path) if suitable_container == container
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# @param import_path [String]
|
98
|
+
# @param observer [SmartCore::Container]
|
99
|
+
# @return [void]
|
100
|
+
#
|
101
|
+
# @api private
|
102
|
+
# @since 0.1.0
|
103
|
+
def register_observer(import_path, observer)
|
104
|
+
observers[import_path] << observer
|
105
|
+
end
|
106
|
+
|
107
|
+
# @return [Array<String>]
|
108
|
+
#
|
109
|
+
# @api private
|
110
|
+
# @since 0.1.0
|
111
|
+
def observed_import_pathes
|
112
|
+
observers.keys
|
113
|
+
end
|
114
|
+
|
115
|
+
# @param import_pathes [String]
|
116
|
+
# @return [void]
|
117
|
+
#
|
118
|
+
# @api private
|
119
|
+
# @since 0.1.0
|
120
|
+
def notify_observers(*import_pathes)
|
121
|
+
import_pathes.each { |import_path| observers.fetch(import_path).each(&:call) }
|
122
|
+
end
|
123
|
+
|
69
124
|
# @param block [Block]
|
70
125
|
# @yield [container]
|
71
126
|
# @yieldparam container [SmartCore::Container]
|
72
|
-
# @return [
|
127
|
+
# @return [Enumerable]
|
73
128
|
#
|
74
129
|
# @api private
|
75
130
|
# @since 0.1.0
|
76
131
|
def each_container(&block)
|
77
|
-
|
78
|
-
|
132
|
+
enumerator = Enumerator.new do |yielder|
|
133
|
+
if explicitly_passed_container
|
134
|
+
yielder.yield(explicitly_passed_container)
|
135
|
+
else
|
136
|
+
registered_containers.reverse_each(&yielder)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
block_given? ? enumerator.each(&block) : enumerator.each
|
79
141
|
end
|
80
142
|
end
|
@@ -20,7 +20,7 @@ class SmartCore::Injection::Locator::Dependency
|
|
20
20
|
# @since 0.1.0
|
21
21
|
def rebind(&block)
|
22
22
|
with_barrier do
|
23
|
-
@
|
23
|
+
@binded = false
|
24
24
|
bind(&block)
|
25
25
|
end
|
26
26
|
end
|
@@ -36,7 +36,7 @@ class SmartCore::Injection::Locator::Dependency
|
|
36
36
|
@value
|
37
37
|
else
|
38
38
|
@binded = true
|
39
|
-
@value = yield
|
39
|
+
@value = yield
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|
@@ -11,8 +11,8 @@ module SmartCore::Injection::Locator::Factory
|
|
11
11
|
# @since 0.1.0
|
12
12
|
def create(injection_settings, import_key, import_path)
|
13
13
|
container_proxy = create_container_proxy(injection_settings)
|
14
|
-
|
15
|
-
|
14
|
+
create_locator(import_path, container_proxy).tap do |locator|
|
15
|
+
control_injection_memoization(injection_settings, container_proxy, locator, import_path)
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
@@ -46,8 +46,10 @@ module SmartCore::Injection::Locator::Factory
|
|
46
46
|
#
|
47
47
|
# @api private
|
48
48
|
# @since 0.1.0
|
49
|
-
def
|
50
|
-
container_proxy.observe(import_path)
|
49
|
+
def control_injection_memoization(injection_settings, container_proxy, locator, import_path)
|
50
|
+
container_proxy.observe(import_path) do
|
51
|
+
locator.rebind!
|
52
|
+
end unless injection_settings.memoize
|
51
53
|
end
|
52
54
|
end
|
53
55
|
end
|
data/smart_injection.gemspec
CHANGED
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.require_paths = ['lib']
|
32
32
|
|
33
33
|
spec.add_runtime_dependency 'smart_engine', '~> 0.7'
|
34
|
-
spec.add_runtime_dependency 'smart_container', '~> 0.
|
34
|
+
spec.add_runtime_dependency 'smart_container', '~> 0.8', '>= 0.8.1'
|
35
35
|
|
36
36
|
spec.add_development_dependency 'bundler', '~> 2.1'
|
37
37
|
spec.add_development_dependency 'rake', '~> 13.0'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smart_injection
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.0.
|
4
|
+
version: 0.0.0.alpha3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rustam Ibragimov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-07-
|
11
|
+
date: 2020-07-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: smart_engine
|
@@ -30,14 +30,20 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0.
|
33
|
+
version: '0.8'
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 0.8.1
|
34
37
|
type: :runtime
|
35
38
|
prerelease: false
|
36
39
|
version_requirements: !ruby/object:Gem::Requirement
|
37
40
|
requirements:
|
38
41
|
- - "~>"
|
39
42
|
- !ruby/object:Gem::Version
|
40
|
-
version: '0.
|
43
|
+
version: '0.8'
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 0.8.1
|
41
47
|
- !ruby/object:Gem::Dependency
|
42
48
|
name: bundler
|
43
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -147,6 +153,7 @@ files:
|
|
147
153
|
- lib/smart_core/injection/errors.rb
|
148
154
|
- lib/smart_core/injection/injector.rb
|
149
155
|
- lib/smart_core/injection/injector/container_set.rb
|
156
|
+
- lib/smart_core/injection/injector/container_set/adding_listener.rb
|
150
157
|
- lib/smart_core/injection/injector/injection_settings.rb
|
151
158
|
- lib/smart_core/injection/injector/injection_settings/incompatability_control.rb
|
152
159
|
- lib/smart_core/injection/injector/modulizer.rb
|