smart_container 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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