smart_container 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 238540cd0bdf9e1753b190d639cf1b0de8876ec5fbe5c5b152235543177079e5
4
- data.tar.gz: aab0620b71b507954e40a3b6e92aee2928432624c3db32b8fdde2a2c7c09a347
3
+ metadata.gz: 8724a62bc6365606a5b796bac2899c5ddba96c179548878f12e324291b6862a3
4
+ data.tar.gz: 769c81de665be07979bbeb8026398ff6cf6e8885159cbe6ab1aff52d07a64095
5
5
  SHA512:
6
- metadata.gz: 21c636030e9b8911c7af18af53d4450676fdf7ca14d3438354bf6da7b0c3375441ee06099fb06774cef311930e418e3d9b95c1b1528826b6f291cef82140195c
7
- data.tar.gz: 9e45275d4c8cea45fc87590650f67b1b677ce44a3b1e3524206e7ebf6ec3dc8f29d6cd3e1e5a0c409a6a5f21cfc268ae65c9c82e51a59dac9154f41fd8dc289f
6
+ metadata.gz: b1f138811f9b345b2f735b4f90e06d44ef83b955358e78b786becb9e2d73144de113cbfc0b08d765c245a7c1a4889bba8f5c3ed63219f28fa312554f8834d1ae
7
+ data.tar.gz: 69da3a3c4ac8b5d34243a617dff6614654a9c116ef7270f7f313127dafe973a2d102143df21fcad222bb9d94499606f983835b74e711a9c823934c58c8bc42a2
@@ -1,6 +1,26 @@
1
1
  # Changelog
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
+ ## [0.2.0] - 202-01-05
5
+ ### Changed
6
+ - (Private API (`SmartCore::Container::RegistryBuilder`)) improved semantics:
7
+ - `build_state` is renamed to `initialise`;
8
+ - `build_definitions` is renamed to `define`;
9
+ - (Public API) Support for memoized dependencies (all dependencies are memoized by default)
10
+ ```ruby
11
+ class MyContainer < SmartCore::Container
12
+ namespace(:some_naespace) do
13
+ # memoized by default
14
+ register(:random_number) { rand(1000) }
15
+ # explicit memoization
16
+ register(:random_number, memoized: true) { rand(1000) }
17
+
18
+ # register non-memoizable dependency
19
+ register(:random_number, memoized: false) { rand(1000) }
20
+ end
21
+ end
22
+ ```
23
+
4
24
  ## [0.1.0] - 2020-01-02
5
25
 
6
26
  - Release :)
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- smart_container (0.1.0)
4
+ smart_container (0.2.0)
5
5
  smart_engine (~> 0.2)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -22,6 +22,39 @@ require 'smart_core/container'
22
22
 
23
23
  ---
24
24
 
25
+ ## Synopsis (demo)
26
+
27
+ ```ruby
28
+ class Container < SmartCore::Container
29
+ namespace(:database) do # support for namespaces
30
+ register(:resolver) { SomeDatabaseResolver.new } # dependency registration
31
+
32
+ namespace(:cache) do # support for nested naespaces
33
+ register(:memcached) { MemcachedClient.new }
34
+ register(:redis) { RedisClient.new }
35
+ end
36
+ end
37
+
38
+ # root dependencies
39
+ register(:logger) { Logger.new(STDOUT) }
40
+
41
+ # do not memoize registered object
42
+ register(:random, memoize: false) { rand(1000) }
43
+ end
44
+
45
+ container = Container.new # create container instance
46
+
47
+ container['database.resolver'] # => #<SomeDatabaseResolver:0x00007f0f0f1d6332>
48
+ container['database.cache.redis'] # => #<RedisClient:0x00007f0f0f1d0158>
49
+ container['logger'] # => #<Logger:0x00007f5f0f2f0158>
50
+
51
+ # non-memoized dependency
52
+ container['random'] # => 352
53
+ container['random'] # => 57
54
+ ```
55
+
56
+ ---
57
+
25
58
  ## Contributing
26
59
 
27
60
  - Fork it ( https://github.com/smart-rb/smart_container/fork )
@@ -63,17 +63,19 @@ class SmartCore::Container
63
63
  end
64
64
 
65
65
  # @param dependency_name [String, Symbol]
66
+ # @option memoize [Boolean]
66
67
  # @param dependency_definition [Block]
67
68
  # @return [void]
68
69
  #
69
70
  # @api public
70
71
  # @since 0.1.0
71
- def register(dependency_name, &dependency_definition)
72
+ # @version 0.2.0
73
+ def register(dependency_name, memoize: true, &dependency_definition)
72
74
  @__container_definition_lock__.thread_safe do
73
75
  DependencyCompatability::Definition.prevent_namespace_overlap!(self, dependency_name)
74
76
 
75
77
  __container_definition_commands__ << Commands::Definition::Register.new(
76
- dependency_name, dependency_definition
78
+ dependency_name, dependency_definition, memoize
77
79
  )
78
80
  end
79
81
  end
@@ -27,7 +27,7 @@ module SmartCore::Container::DefinitionDSL::Commands::Definition
27
27
  # @api private
28
28
  # @since 0.1.0
29
29
  def call(registry)
30
- SmartCore::Container::RegistryBuilder.build_definitions(container_klass, registry)
30
+ SmartCore::Container::RegistryBuilder.define(container_klass, registry)
31
31
  end
32
32
 
33
33
  # @return [SmartCore::Container::DefinitionDSL::Commands::Definition::Compose]
@@ -15,14 +15,17 @@ module SmartCore::Container::DefinitionDSL::Commands::Definition
15
15
 
16
16
  # @param dependency_name [String, Symbol]
17
17
  # @param dependency_definition [Proc]
18
+ # @param memoize [Boolean]
18
19
  # @return [void]
19
20
  #
20
21
  # @api private
21
22
  # @since 0.1.0
22
- def initialize(dependency_name, dependency_definition)
23
+ # @version 0.2.0
24
+ def initialize(dependency_name, dependency_definition, memoize)
23
25
  SmartCore::Container::KeyGuard.indifferently_accessable_key(dependency_name).tap do |name|
24
26
  @dependency_name = name
25
27
  @dependency_definition = dependency_definition
28
+ @memoize = memoize
26
29
  end
27
30
  end
28
31
 
@@ -31,16 +34,18 @@ module SmartCore::Container::DefinitionDSL::Commands::Definition
31
34
  #
32
35
  # @api private
33
36
  # @since 0.1.0
37
+ # @version 0.2.0
34
38
  def call(registry)
35
- registry.register_dependency(dependency_name, &dependency_definition)
39
+ registry.register_dependency(dependency_name, memoize, &dependency_definition)
36
40
  end
37
41
 
38
42
  # @return [SmartCore::Container::DefinitionDSL::Commands::Definition::Register]
39
43
  #
40
44
  # @api private
41
45
  # @since 0.1.0
46
+ # @version 0.2.0
42
47
  def dup
43
- self.class.new(dependency_name, dependency_definition)
48
+ self.class.new(dependency_name, dependency_definition, memoize)
44
49
  end
45
50
 
46
51
  private
@@ -50,5 +55,11 @@ module SmartCore::Container::DefinitionDSL::Commands::Definition
50
55
  # @api private
51
56
  # @since 0.1.0
52
57
  attr_reader :dependency_definition
58
+
59
+ # @return [Boolean]
60
+ #
61
+ # @api private
62
+ # @since 0.2.0
63
+ attr_reader :memoize
53
64
  end
54
65
  end
@@ -27,7 +27,7 @@ module SmartCore::Container::DefinitionDSL::Commands::Instantiation
27
27
  # @api private
28
28
  # @since 0.1.0
29
29
  def call(registry)
30
- SmartCore::Container::RegistryBuilder.build_state(
30
+ SmartCore::Container::RegistryBuilder.instantiate(
31
31
  container_klass, registry, ignored_commands: [
32
32
  SmartCore::Container::DefinitionDSL::Commands::Instantiation::FreezeState
33
33
  ]
@@ -5,6 +5,7 @@
5
5
  module SmartCore::Container::Entities
6
6
  require_relative 'entities/base'
7
7
  require_relative 'entities/dependency'
8
+ require_relative 'entities/memoized_dependency'
8
9
  require_relative 'entities/dependency_builder'
9
10
  require_relative 'entities/namespace'
10
11
  require_relative 'entities/namespace_builder'
@@ -6,32 +6,38 @@ class SmartCore::Container::Entities::DependencyBuilder
6
6
  class << self
7
7
  # @param dependency_name [String]
8
8
  # @param dependency_definition [Proc]
9
+ # @param memoize [Boolean]
9
10
  # @return [SmartCore::Container::Entities::Dependency]
10
11
  #
11
12
  # @api private
12
13
  # @since 0.1.0
13
- def build(dependency_name, dependency_definition)
14
- new(dependency_name, dependency_definition).build
14
+ # @version 0.2.0
15
+ def build(dependency_name, dependency_definition, memoize)
16
+ new(dependency_name, dependency_definition, memoize).build
15
17
  end
16
18
  end
17
19
 
18
20
  # @param dependency_name [String]
19
21
  # @param dependency_definition [Proc]
22
+ # @param memoize [Boolean]
20
23
  # @return [void]
21
24
  #
22
25
  # @api private
23
26
  # @since 0.1.0
24
- def initialize(dependency_name, dependency_definition)
27
+ # @version 0.2.0
28
+ def initialize(dependency_name, dependency_definition, memoize)
25
29
  @dependency_name = dependency_name
26
30
  @dependency_definition = dependency_definition
31
+ @memoize = memoize
27
32
  end
28
33
 
29
34
  # @return [SmartCore::Container::Entities::Dependency]
30
35
  #
31
36
  # @api private
32
37
  # @since 0.1.0
38
+ # @version 0.2.0
33
39
  def build
34
- SmartCore::Container::Entities::Dependency.new(dependency_name, dependency_definition)
40
+ memoize ? build_memoized_dependency : build_original_dependency
35
41
  end
36
42
 
37
43
  private
@@ -47,4 +53,26 @@ class SmartCore::Container::Entities::DependencyBuilder
47
53
  # @api private
48
54
  # @since 0.1.0
49
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
70
+
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)
77
+ end
50
78
  end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SmartCore::Container::Entities
4
+ # @api private
5
+ # @since 0.2.0
6
+ class MemoizedDependency < Dependency
7
+ # @param dependency_name [String]
8
+ # @param dependency_definition [Proc]
9
+ # @return [void]
10
+ #
11
+ # @api private
12
+ # @since 0.2.0
13
+ def initialize(dependency_name, dependency_definition)
14
+ super(dependency_name, dependency_definition)
15
+ @lock = SmartCore::Container::ArbitaryLock.new
16
+ end
17
+
18
+ # @return [Any]
19
+ #
20
+ # @api private
21
+ # @since 0.2.0
22
+ def reveal
23
+ @lock.thread_safe do
24
+ unless instance_variable_defined?(:@revealed_dependency)
25
+ @revealed_dependency = dependency_definition.call
26
+ else
27
+ @revealed_dependency
28
+ end
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ # @return [Proc]
35
+ #
36
+ # @api private
37
+ # @since 0.2.0
38
+ attr_reader :dependency_definition
39
+ end
40
+ end
@@ -32,13 +32,15 @@ class SmartCore::Container::Registry
32
32
  end
33
33
 
34
34
  # @param name [String, Symbol]
35
+ # @param memoize [Boolean]
35
36
  # @param dependency_definition [Block]
36
37
  # @return [void]
37
38
  #
38
39
  # @api private
39
40
  # @since 0.1.0
40
- def register_dependency(name, &dependency_definition)
41
- thread_safe { add_dependency(name, dependency_definition) }
41
+ # @version 0.2.0
42
+ def register_dependency(name, memoize = true, &dependency_definition)
43
+ thread_safe { add_dependency(name, dependency_definition, memoize) }
42
44
  end
43
45
 
44
46
  # @param name [String, Symbol]
@@ -157,13 +159,15 @@ class SmartCore::Container::Registry
157
159
 
158
160
  # @param dependency_name [String, Symbol]
159
161
  # @param dependency_definition [Proc]
162
+ # @param memoize [Boolean]
160
163
  # @return [SmartCore::Container::Entities::Dependency]
161
164
  #
162
165
  # @raise [SmartCore::Container::DependencyOverNamespaceOverlapError]
163
166
  #
164
167
  # @api private
165
168
  # @since 0.1.0
166
- def add_dependency(dependency_name, dependency_definition)
169
+ # @version 0.2.0
170
+ def add_dependency(dependency_name, dependency_definition, memoize)
167
171
  if state_frozen?
168
172
  raise(SmartCore::Container::FrozenRegistryError, 'Can not modify frozen registry!')
169
173
  end
@@ -171,7 +175,7 @@ class SmartCore::Container::Registry
171
175
  prevent_namespace_overlap!(dependency_name)
172
176
 
173
177
  dependency_entity = SmartCore::Container::Entities::DependencyBuilder.build(
174
- dependency_name, dependency_definition
178
+ dependency_name, dependency_definition, memoize
175
179
  )
176
180
 
177
181
  dependency_entity.tap { registry[dependency_name] = dependency_entity }
@@ -14,8 +14,8 @@ module SmartCore::Container::RegistryBuilder
14
14
  # @since 0.1.0
15
15
  def build(container, ignored_definition_commands: [], ignored_instantiation_commands: [])
16
16
  SmartCore::Container::Registry.new.tap do |registry|
17
- build_definitions(container.class, registry, ignored_commands: ignored_definition_commands)
18
- build_state(container.class, registry, ignored_commands: ignored_instantiation_commands)
17
+ define(container.class, registry, ignored_commands: ignored_definition_commands)
18
+ instantiate(container.class, registry, ignored_commands: ignored_instantiation_commands)
19
19
  end
20
20
  end
21
21
 
@@ -26,7 +26,7 @@ module SmartCore::Container::RegistryBuilder
26
26
  #
27
27
  # @api private
28
28
  # @since 0.1.0
29
- def build_definitions(container_klass, registry, ignored_commands: [])
29
+ def define(container_klass, registry, ignored_commands: [])
30
30
  container_klass.__container_definition_commands__.each do |command|
31
31
  next if ignored_commands.include?(command.class)
32
32
  command.call(registry)
@@ -40,7 +40,7 @@ module SmartCore::Container::RegistryBuilder
40
40
  #
41
41
  # @api private
42
42
  # @since 0.1.0
43
- def build_state(container_klass, registry, ignored_commands: [])
43
+ def instantiate(container_klass, registry, ignored_commands: [])
44
44
  container_klass.__container_instantiation_commands__.each do |command|
45
45
  next if ignored_commands.include?(command.class)
46
46
  command.call(registry)
@@ -4,6 +4,7 @@ module SmartCore
4
4
  class Container
5
5
  # @api public
6
6
  # @since 0.1.0
7
- VERSION = '0.1.0'
7
+ # @version 0.2.0
8
+ VERSION = '0.2.0'
8
9
  end
9
10
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smart_container
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
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-01-02 00:00:00.000000000 Z
11
+ date: 2020-01-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: smart_engine
@@ -153,6 +153,7 @@ files:
153
153
  - lib/smart_core/container/entities/base.rb
154
154
  - lib/smart_core/container/entities/dependency.rb
155
155
  - lib/smart_core/container/entities/dependency_builder.rb
156
+ - lib/smart_core/container/entities/memoized_dependency.rb
156
157
  - lib/smart_core/container/entities/namespace.rb
157
158
  - lib/smart_core/container/entities/namespace_builder.rb
158
159
  - lib/smart_core/container/errors.rb