smart_container 0.4.0 → 0.8.1

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.
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 0.8.0
5
+ class SmartCore::Container::DependencyWatcher::Observer
6
+ # @param container [SmartCore::Container]
7
+ # @param dependency_path [String]
8
+ # @param callback [Proc]
9
+ # @return [void]
10
+ #
11
+ # @api private
12
+ # @since 0.8.0
13
+ def initialize(container, dependency_path, callback)
14
+ @container = container
15
+ @dependency_path = dependency_path
16
+ @callback = callback
17
+ end
18
+
19
+ # @return [void]
20
+ #
21
+ # @api private
22
+ # @since 0.8.0
23
+ def notify!
24
+ callback.call(dependency_path, container)
25
+ end
26
+
27
+ private
28
+
29
+ # @return [SmartCore::Container]
30
+ #
31
+ # @api private
32
+ # @since 0.8.0
33
+ attr_reader :container
34
+
35
+ # @return [String]
36
+ #
37
+ # @api private
38
+ # @since 0.8.0
39
+ attr_reader :dependency_path
40
+
41
+ # @return [Proc]
42
+ #
43
+ # @api private
44
+ # @since 0.8.0
45
+ attr_reader :callback
46
+ end
@@ -20,11 +20,13 @@ class SmartCore::Container::Entities::Dependency < SmartCore::Container::Entitie
20
20
  @dependency_definition = dependency_definition
21
21
  end
22
22
 
23
+ # @param host_container [SmartCore::Container, NilClass]
23
24
  # @return [Any]
24
25
  #
25
26
  # @api private
26
27
  # @since 0.1.0
27
- def reveal
28
+ # @version 0.8.1
29
+ def reveal(host_container = SmartCore::Container::NO_HOST_CONTAINER)
28
30
  dependency_definition.call
29
31
  end
30
32
 
@@ -2,7 +2,8 @@
2
2
 
3
3
  # @api private
4
4
  # @since 0.1.0
5
- class SmartCore::Container::Entities::DependencyBuilder
5
+ # @version 0.8.1
6
+ module SmartCore::Container::Entities::DependencyBuilder
6
7
  class << self
7
8
  # @param dependency_name [String]
8
9
  # @param dependency_definition [Proc]
@@ -11,68 +12,35 @@ class SmartCore::Container::Entities::DependencyBuilder
11
12
  #
12
13
  # @api private
13
14
  # @since 0.1.0
14
- # @version 0.2.0
15
+ # @version 0.8.1
15
16
  def build(dependency_name, dependency_definition, memoize)
16
- new(dependency_name, dependency_definition, memoize).build
17
+ if memoize
18
+ build_memoized_dependency(dependency_name, dependency_definition)
19
+ else
20
+ build_original_dependency(dependency_name, dependency_definition)
21
+ end
17
22
  end
18
- end
19
-
20
- # @param dependency_name [String]
21
- # @param dependency_definition [Proc]
22
- # @param memoize [Boolean]
23
- # @return [void]
24
- #
25
- # @api private
26
- # @since 0.1.0
27
- # @version 0.2.0
28
- def initialize(dependency_name, dependency_definition, memoize)
29
- @dependency_name = dependency_name
30
- @dependency_definition = dependency_definition
31
- @memoize = memoize
32
- end
33
-
34
- # @return [SmartCore::Container::Entities::Dependency]
35
- #
36
- # @api private
37
- # @since 0.1.0
38
- # @version 0.2.0
39
- def build
40
- memoize ? build_memoized_dependency : build_original_dependency
41
- end
42
-
43
- private
44
23
 
45
- # @return [String]
46
- #
47
- # @api private
48
- # @since 0.1.0
49
- attr_reader :dependency_name
24
+ private
50
25
 
51
- # @return [Proc]
52
- #
53
- # @api private
54
- # @since 0.1.0
55
- attr_reader :dependency_definition
56
-
57
- # @return [Boolean]
58
- #
59
- # @api private
60
- # @since 0.2.0
61
- attr_reader :memoize
62
-
63
- # @return [SmartCore::Container::Entities::Dependency]
64
- #
65
- # @api private
66
- # @since 0.2.0
67
- def build_memoized_dependency
68
- SmartCore::Container::Entities::MemoizedDependency.new(dependency_name, dependency_definition)
69
- end
26
+ # @param dependency_name [String]
27
+ # @param dependency_definition [Proc]
28
+ # @return [SmartCore::Container::Entities::Dependency]
29
+ #
30
+ # @api private
31
+ # @since 0.8.1
32
+ def build_memoized_dependency(dependency_name, dependency_definition)
33
+ SmartCore::Container::Entities::MemoizedDependency.new(dependency_name, dependency_definition)
34
+ end
70
35
 
71
- # @return [SmartCore::Container::Entities::Dependency]
72
- #
73
- # @api private
74
- # @since 0.2.0
75
- def build_original_dependency
76
- SmartCore::Container::Entities::Dependency.new(dependency_name, dependency_definition)
36
+ # @param dependency_name [String]
37
+ # @param dependency_definition [Proc]
38
+ # @return [SmartCore::Container::Entities::Dependency]
39
+ #
40
+ # @api private
41
+ # @since 0.8.1
42
+ def build_original_dependency(dependency_name, dependency_definition)
43
+ SmartCore::Container::Entities::Dependency.new(dependency_name, dependency_definition)
44
+ end
77
45
  end
78
46
  end
@@ -12,14 +12,16 @@ module SmartCore::Container::Entities
12
12
  # @since 0.2.0
13
13
  def initialize(dependency_name, dependency_definition)
14
14
  super(dependency_name, dependency_definition)
15
- @lock = SmartCore::Container::ArbitaryLock.new
15
+ @lock = SmartCore::Container::ArbitraryLock.new
16
16
  end
17
17
 
18
+ # @param host_container [SmartCore::Container, NilClass]
18
19
  # @return [Any]
19
20
  #
20
21
  # @api private
21
22
  # @since 0.2.0
22
- def reveal
23
+ # @version 0.8.1
24
+ def reveal(host_container = SmartCore::Container::NO_HOST_CONTAINER)
23
25
  @lock.thread_safe do
24
26
  unless instance_variable_defined?(:@revealed_dependency)
25
27
  @revealed_dependency = dependency_definition.call
@@ -9,24 +9,35 @@ class SmartCore::Container::Entities::Namespace < SmartCore::Container::Entities
9
9
  # @since 0.1.0
10
10
  alias_method :namespace_name, :external_name
11
11
 
12
+ # @return [NilClass, SmartCore::Container]
13
+ #
14
+ # @api private
15
+ # @since 0.8.01
16
+ attr_reader :host_container
17
+
12
18
  # @param namespace_name [String]
19
+ # @param host_container [NilClass, SmartCore::Container]
13
20
  # @return [void]
14
21
  #
15
22
  # @api private
16
23
  # @since 0.1.0
17
- def initialize(namespace_name)
24
+ # @version 0.8.1
25
+ def initialize(namespace_name, host_container = SmartCore::Container::NO_HOST_CONTAINER)
18
26
  super(namespace_name)
19
27
  @container_klass = Class.new(SmartCore::Container)
20
28
  @container_instance = nil
21
- @lock = SmartCore::Container::ArbitaryLock.new
29
+ @host_container = host_container
30
+ @lock = SmartCore::Container::ArbitraryLock.new
22
31
  end
23
32
 
33
+ # @param runtime_host_container [SmartCore::Container, NilClass]
24
34
  # @return [SmartCore::Container]
25
35
  #
26
36
  # @api private
27
37
  # @since 0.1.0
28
- def reveal
29
- thread_safe { container_instance }
38
+ # @version 0.8.1
39
+ def reveal(runtime_host_container = SmartCore::Container::NO_HOST_CONTAINER)
40
+ thread_safe { container_instance(runtime_host_container) }
30
41
  end
31
42
 
32
43
  # @param dependencies_definition [Proc]
@@ -54,12 +65,18 @@ class SmartCore::Container::Entities::Namespace < SmartCore::Container::Entities
54
65
  # @since 0.1.0
55
66
  attr_reader :container_klass
56
67
 
68
+ # @param runtime_host_container [SmartCore::Container, NilClass]
57
69
  # @return [SmartCore::Container]
58
70
  #
59
71
  # @api private
60
72
  # @since 0.1.0
61
- def container_instance
62
- @container_instance ||= container_klass.new
73
+ # @version 0.8.1
74
+ def container_instance(runtime_host_container = SmartCore::Container::NO_HOST_CONTAINER)
75
+ @host_container ||= runtime_host_container
76
+ @container_instance ||= container_klass.new(
77
+ host_container: @host_container,
78
+ host_path: @host_container && namespace_name
79
+ )
63
80
  end
64
81
 
65
82
  # @param block [Block]
@@ -2,40 +2,20 @@
2
2
 
3
3
  # @api private
4
4
  # @since 0.1.0
5
- class SmartCore::Container::Entities::NamespaceBuilder
6
- class << self
7
- # @param namespace_name [String]
8
- # @return [SmartCore::Container::Entities::Namespace]
9
- #
10
- # @api private
11
- # @since 0.1.0
12
- def build(namespace_name)
13
- new(namespace_name).build
5
+ # @version 0.8.1
6
+ module SmartCore::Container::Entities
7
+ module NamespaceBuilder
8
+ class << self
9
+ # @param namespace_name [String]
10
+ # @param host_container [SmartContainer, NilClass]
11
+ # @return [SmartCore::Container::Entities::Namespace]
12
+ #
13
+ # @api private
14
+ # @since 0.1.0
15
+ # @version 0.8.1
16
+ def build(namespace_name, host_container = SmartCore::Container::NO_HOST_CONTAINER)
17
+ SmartCore::Container::Entities::Namespace.new(namespace_name, host_container)
18
+ end
14
19
  end
15
20
  end
16
-
17
- # @param namespace_name [String]
18
- # @return [void]
19
- #
20
- # @api private
21
- # @since 0.1.0
22
- def initialize(namespace_name)
23
- @namespace_name = namespace_name
24
- end
25
-
26
- # @return [SmartCore::Container::Entities::Namespace]
27
- #
28
- # @api private
29
- # @since 0.1.0
30
- def build
31
- SmartCore::Container::Entities::Namespace.new(namespace_name)
32
- end
33
-
34
- private
35
-
36
- # @return [String]
37
- #
38
- # @api private
39
- # @since 0.1.0
40
- attr_reader :namespace_name
41
21
  end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 0.8.1
5
+ class SmartCore::Container::Host
6
+ class << self
7
+ # @param container [SmartCore::Container]
8
+ # @param path [String]
9
+ # @return [SmartCore::Container::Host]
10
+ #
11
+ # @api private
12
+ # @since 0.8.1
13
+ def build(container, path) # rubocop:disable Metrics/AbcSize
14
+ if (container.nil? && !path.nil?) || (!container.nil? && path.nil?)
15
+ raise(SmartCore::Container::ArgumentError, <<~ERROR_MESSAGE)
16
+ Host container requires both host container instance and host container path
17
+ (container: #{container.inspect} / path: #{path.inspect})
18
+ ERROR_MESSAGE
19
+ end
20
+
21
+ if (!container.nil? && !path.nil?) &&
22
+ (!container.is_a?(SmartCore::Container) || !path.is_a?(String))
23
+ raise(SmartCore::Container::ArgumentError, <<~ERROR_MESSAGE)
24
+ Host container should be a type of SmartCore::Container
25
+ and host path should be a type of String.
26
+ ERROR_MESSAGE
27
+ end
28
+
29
+ new(container, path)
30
+ end
31
+ end
32
+
33
+ # @return [SmartCore::Container]
34
+ #
35
+ # @api private
36
+ # @since 0.8.1
37
+ attr_reader :container
38
+
39
+ # @return [String]
40
+ #
41
+ # @api private
42
+ # @since 0.8.1
43
+ attr_reader :path
44
+
45
+ # @return [Boolean]
46
+ #
47
+ # @api private
48
+ # @since 0.8.1
49
+ attr_reader :exists
50
+ alias_method :exists?, :exists
51
+ alias_method :present?, :exists
52
+
53
+ # @param container [SmartCore::Container]
54
+ # @param path [String]
55
+ # @return [void]
56
+ #
57
+ # @api private
58
+ # @since 0.8.1
59
+ def initialize(container, path)
60
+ @container = container
61
+ @path = path
62
+ @exists = !!container
63
+ end
64
+
65
+ # @param nested_entity_path [String]
66
+ # @return [void]
67
+ #
68
+ # @api private
69
+ # @since 0.8.1
70
+ def notify_about_nested_changement(nested_entity_path)
71
+ return unless exists?
72
+ host_path = "#{path}" \
73
+ "#{SmartCore::Container::DependencyResolver::PATH_PART_SEPARATOR}" \
74
+ "#{nested_entity_path}"
75
+ container.watcher.notify(host_path)
76
+ end
77
+ end
@@ -11,7 +11,7 @@ module SmartCore::Container::Mixin
11
11
  # @since 0.1.0
12
12
  def included(base_klass)
13
13
  # rubocop:disable Layout/LineLength
14
- base_klass.instance_variable_set(:@__smart_core_container_access_lock__, SmartCore::Container::ArbitaryLock.new)
14
+ base_klass.instance_variable_set(:@__smart_core_container_access_lock__, SmartCore::Container::ArbitraryLock.new)
15
15
  base_klass.instance_variable_set(:@__smart_core_container_klass__, Class.new(SmartCore::Container))
16
16
  base_klass.instance_variable_set(:@__smart_core_container__, nil)
17
17
  # rubocop:enable Layout/LineLength
@@ -34,7 +34,7 @@ module SmartCore::Container::Mixin
34
34
  inherited_container_klass = Class.new(@__smart_core_container_klass__)
35
35
 
36
36
  # rubocop:disable Layout/LineLength
37
- child_klass.instance_variable_set(:@__smart_core_container_access_lock__, SmartCore::Container::ArbitaryLock.new)
37
+ child_klass.instance_variable_set(:@__smart_core_container_access_lock__, SmartCore::Container::ArbitraryLock.new)
38
38
  child_klass.instance_variable_set(:@__smart_core_container_klass__, inherited_container_klass)
39
39
  child_klass.instance_variable_set(:@__smart_core_container__, nil)
40
40
  # rubocop:enable Layout/LineLength
@@ -37,7 +37,7 @@ class SmartCore::Container::Registry
37
37
  # @since 0.1.0
38
38
  def initialize
39
39
  @registry = {}
40
- @access_lock = SmartCore::Container::ArbitaryLock.new
40
+ @access_lock = SmartCore::Container::ArbitraryLock.new
41
41
  end
42
42
 
43
43
  # @param entity_path [String, Symbol]
@@ -57,18 +57,24 @@ class SmartCore::Container::Registry
57
57
  # @api private
58
58
  # @since 0.1.0
59
59
  # @version 0.3.0
60
- def register_dependency(name, memoize = DEFAULT_MEMOIZATION_BEHAVIOR, &dependency_definition)
60
+ def register_dependency(name, memoize: DEFAULT_MEMOIZATION_BEHAVIOR, &dependency_definition)
61
61
  thread_safe { add_dependency(name, dependency_definition, memoize) }
62
62
  end
63
63
 
64
64
  # @param name [String, Symbol]
65
+ # @param host_container [NilClasss, SmartCore::Container]
65
66
  # @param dependencies_definition [Block]
66
67
  # @return [void]
67
68
  #
68
69
  # @api private
69
70
  # @since 0.1.0
70
- def register_namespace(name, &dependencies_definition)
71
- thread_safe { add_namespace(name, dependencies_definition) }
71
+ # @version 0.8.1
72
+ def register_namespace(
73
+ name,
74
+ host_container = SmartCore::Container::NO_HOST_CONTAINER,
75
+ &dependencies_definition
76
+ )
77
+ thread_safe { add_namespace(name, host_container, dependencies_definition) }
72
78
  end
73
79
 
74
80
  # @return [void]
@@ -223,6 +229,7 @@ class SmartCore::Container::Registry
223
229
  end
224
230
 
225
231
  # @param namespace_name [String, Symbol]
232
+ # @param host_container [NilClass, SmartCore::Container]
226
233
  # @param dependencies_definition [Proc]
227
234
  # @return [SmartCore::Container::Entities::Namespace]
228
235
  #
@@ -230,11 +237,13 @@ class SmartCore::Container::Registry
230
237
  #
231
238
  # @api private
232
239
  # @since 0.1.0
233
- def add_namespace(namespace_name, dependencies_definition)
240
+ # @version 0.8.1
241
+ def add_namespace(namespace_name, host_container, dependencies_definition)
234
242
  if state_frozen?
235
243
  raise(SmartCore::Container::FrozenRegistryError, 'Can not modify frozen registry!')
236
244
  end
237
245
  namespace_name = indifferently_accessable_name(namespace_name)
246
+ dependencies_definition ||= proc {}
238
247
  prevent_dependency_overlap!(namespace_name)
239
248
 
240
249
  # rubocop:disable Layout/RescueEnsureAlignment
@@ -242,7 +251,7 @@ class SmartCore::Container::Registry
242
251
  fetch_entity(namespace_name)
243
252
  rescue SmartCore::Container::FetchError
244
253
  registry[namespace_name] = SmartCore::Container::Entities::NamespaceBuilder.build(
245
- namespace_name
254
+ namespace_name, host_container
246
255
  )
247
256
  end
248
257
  # rubocop:enable Layout/RescueEnsureAlignment