smart_container 0.1.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 +7 -0
- data/.gitignore +12 -0
- data/.rspec +3 -0
- data/.rubocop.yml +15 -0
- data/.travis.yml +28 -0
- data/CHANGELOG.md +6 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +83 -0
- data/LICENSE.txt +21 -0
- data/README.md +39 -0
- data/Rakefile +21 -0
- data/bin/console +8 -0
- data/bin/setup +8 -0
- data/lib/smart_core/container.rb +135 -0
- data/lib/smart_core/container/arbitary_lock.rb +22 -0
- data/lib/smart_core/container/definition_dsl.rb +109 -0
- data/lib/smart_core/container/definition_dsl/command_set.rb +87 -0
- data/lib/smart_core/container/definition_dsl/commands.rb +9 -0
- data/lib/smart_core/container/definition_dsl/commands/base.rb +48 -0
- data/lib/smart_core/container/definition_dsl/commands/definition.rb +9 -0
- data/lib/smart_core/container/definition_dsl/commands/definition/compose.rb +49 -0
- data/lib/smart_core/container/definition_dsl/commands/definition/namespace.rb +54 -0
- data/lib/smart_core/container/definition_dsl/commands/definition/register.rb +54 -0
- data/lib/smart_core/container/definition_dsl/commands/instantiation.rb +8 -0
- data/lib/smart_core/container/definition_dsl/commands/instantiation/compose.rb +53 -0
- data/lib/smart_core/container/definition_dsl/commands/instantiation/freeze_state.rb +27 -0
- data/lib/smart_core/container/definition_dsl/inheritance.rb +23 -0
- data/lib/smart_core/container/dependency_compatability.rb +9 -0
- data/lib/smart_core/container/dependency_compatability/definition.rb +38 -0
- data/lib/smart_core/container/dependency_compatability/general.rb +61 -0
- data/lib/smart_core/container/dependency_compatability/registry.rb +36 -0
- data/lib/smart_core/container/dependency_resolver.rb +93 -0
- data/lib/smart_core/container/dependency_resolver/route.rb +83 -0
- data/lib/smart_core/container/dependency_resolver/route/cursor.rb +47 -0
- data/lib/smart_core/container/entities.rb +11 -0
- data/lib/smart_core/container/entities/base.rb +26 -0
- data/lib/smart_core/container/entities/dependency.rb +38 -0
- data/lib/smart_core/container/entities/dependency_builder.rb +50 -0
- data/lib/smart_core/container/entities/namespace.rb +73 -0
- data/lib/smart_core/container/entities/namespace_builder.rb +41 -0
- data/lib/smart_core/container/errors.rb +65 -0
- data/lib/smart_core/container/key_guard.rb +31 -0
- data/lib/smart_core/container/mixin.rb +83 -0
- data/lib/smart_core/container/registry.rb +250 -0
- data/lib/smart_core/container/registry_builder.rb +51 -0
- data/lib/smart_core/container/version.rb +9 -0
- data/smart_container.gemspec +38 -0
- metadata +191 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.1.0
|
5
|
+
class SmartCore::Container::ArbitaryLock
|
6
|
+
# @return [void]
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
# @since 0.1.0
|
10
|
+
def initialize
|
11
|
+
@lock = Mutex.new
|
12
|
+
end
|
13
|
+
|
14
|
+
# @param block [Proc]
|
15
|
+
# @return [Any]
|
16
|
+
#
|
17
|
+
# @api private
|
18
|
+
# @since 0.1.0
|
19
|
+
def thread_safe(&block)
|
20
|
+
@lock.owned? ? yield : @lock.synchronize(&block)
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class SmartCore::Container
|
4
|
+
# @api private
|
5
|
+
# @since 0.1.0
|
6
|
+
module DefinitionDSL
|
7
|
+
require_relative 'definition_dsl/commands'
|
8
|
+
require_relative 'definition_dsl/command_set'
|
9
|
+
require_relative 'definition_dsl/inheritance'
|
10
|
+
|
11
|
+
class << self
|
12
|
+
# @param base_klass [Class<SmartCore::Container>]
|
13
|
+
# @return [void]
|
14
|
+
#
|
15
|
+
# @api private
|
16
|
+
# @since 0.1.0
|
17
|
+
def included(base_klass)
|
18
|
+
base_klass.instance_variable_set(:@__container_definition_commands__, CommandSet.new)
|
19
|
+
base_klass.instance_variable_set(:@__container_instantiation_commands__, CommandSet.new)
|
20
|
+
base_klass.instance_variable_set(:@__container_definition_lock__, ArbitaryLock.new)
|
21
|
+
base_klass.singleton_class.send(:attr_reader, :__container_definition_commands__)
|
22
|
+
base_klass.singleton_class.send(:attr_reader, :__container_instantiation_commands__)
|
23
|
+
base_klass.extend(ClassMethods)
|
24
|
+
base_klass.singleton_class.prepend(ClassInheritance)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# @api private
|
29
|
+
# @since 0.1.0
|
30
|
+
module ClassInheritance
|
31
|
+
# @param child_klass [Class<SmartCore::Container>]
|
32
|
+
# @return [void]
|
33
|
+
#
|
34
|
+
# @api private
|
35
|
+
# @since 0.1.0
|
36
|
+
def inherited(child_klass)
|
37
|
+
child_klass.instance_variable_set(:@__container_definition_commands__, CommandSet.new)
|
38
|
+
child_klass.instance_variable_set(:@__container_instantiation_commands__, CommandSet.new)
|
39
|
+
child_klass.instance_variable_set(:@__container_definition_lock__, ArbitaryLock.new)
|
40
|
+
SmartCore::Container::DefinitionDSL::Inheritance.inherit(base: self, child: child_klass)
|
41
|
+
child_klass.singleton_class.prepend(ClassInheritance)
|
42
|
+
super
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# @api private
|
47
|
+
# @since 0.1.0
|
48
|
+
module ClassMethods
|
49
|
+
# @param namespace_name [String, Symbol]
|
50
|
+
# @param dependencies_definition [Block]
|
51
|
+
# @return [void]
|
52
|
+
#
|
53
|
+
# @api public
|
54
|
+
# @since 0.1.0
|
55
|
+
def namespace(namespace_name, &dependencies_definition)
|
56
|
+
@__container_definition_lock__.thread_safe do
|
57
|
+
DependencyCompatability::Definition.prevent_dependency_overlap!(self, namespace_name)
|
58
|
+
|
59
|
+
__container_definition_commands__ << Commands::Definition::Namespace.new(
|
60
|
+
namespace_name, dependencies_definition
|
61
|
+
)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# @param dependency_name [String, Symbol]
|
66
|
+
# @param dependency_definition [Block]
|
67
|
+
# @return [void]
|
68
|
+
#
|
69
|
+
# @api public
|
70
|
+
# @since 0.1.0
|
71
|
+
def register(dependency_name, &dependency_definition)
|
72
|
+
@__container_definition_lock__.thread_safe do
|
73
|
+
DependencyCompatability::Definition.prevent_namespace_overlap!(self, dependency_name)
|
74
|
+
|
75
|
+
__container_definition_commands__ << Commands::Definition::Register.new(
|
76
|
+
dependency_name, dependency_definition
|
77
|
+
)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# @param container_klass [Class<SmartCore::Container>]
|
82
|
+
# @return [void]
|
83
|
+
#
|
84
|
+
# @api public
|
85
|
+
# @since 0.1.0
|
86
|
+
def compose(container_klass)
|
87
|
+
@__container_definition_lock__.thread_safe do
|
88
|
+
__container_definition_commands__ << Commands::Definition::Compose.new(
|
89
|
+
container_klass
|
90
|
+
)
|
91
|
+
|
92
|
+
__container_instantiation_commands__ << Commands::Instantiation::Compose.new(
|
93
|
+
container_klass
|
94
|
+
)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# @return [void]
|
99
|
+
#
|
100
|
+
# @api public
|
101
|
+
# @since 0.1.0
|
102
|
+
def freeze_state!
|
103
|
+
@__container_definition_lock__.thread_safe do
|
104
|
+
__container_instantiation_commands__ << Commands::Instantiation::FreezeState.new
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.1.0
|
5
|
+
class SmartCore::Container::DefinitionDSL::CommandSet
|
6
|
+
# @since 0.1.0
|
7
|
+
include Enumerable
|
8
|
+
|
9
|
+
# @return [Array<SmartCore::Container::DefinitionDSL::Commands::Base>]
|
10
|
+
#
|
11
|
+
# @api private
|
12
|
+
# @since 0.1.0
|
13
|
+
attr_reader :commands
|
14
|
+
|
15
|
+
# @return [void]
|
16
|
+
#
|
17
|
+
# @api private
|
18
|
+
# @since 0.1.0
|
19
|
+
def initialize
|
20
|
+
@commands = []
|
21
|
+
@access_lock = SmartCore::Container::ArbitaryLock.new
|
22
|
+
end
|
23
|
+
|
24
|
+
# @param [SmartCore::Container::DefinitionDSL::Commands::Base]
|
25
|
+
# @return [void]
|
26
|
+
#
|
27
|
+
# @api private
|
28
|
+
# @since 0.1.0
|
29
|
+
def add_command(command)
|
30
|
+
thread_safe { commands << command }
|
31
|
+
end
|
32
|
+
alias_method :<<, :add_command
|
33
|
+
|
34
|
+
# @param block [Block]
|
35
|
+
# @return [Enumerable]
|
36
|
+
#
|
37
|
+
# @api private
|
38
|
+
# @since 0.1.0
|
39
|
+
def each(&block)
|
40
|
+
thread_safe { block_given? ? commands.each(&block) : commands.each }
|
41
|
+
end
|
42
|
+
|
43
|
+
# @param command_set [SmartCore::Container::DefinitionDSL::CommandSet]
|
44
|
+
# @param concat_condition [Block]
|
45
|
+
# @yield [command]
|
46
|
+
# @yieldparam command [SmartCore::Container::DefinitionDSL::Commands::Base]
|
47
|
+
# @return [void]
|
48
|
+
#
|
49
|
+
# @api private
|
50
|
+
# @since 0.1.0
|
51
|
+
def concat(command_set, &concat_condition)
|
52
|
+
thread_safe do
|
53
|
+
if block_given?
|
54
|
+
command_set.dup.each { |command| (commands << command) if yield(command) }
|
55
|
+
else
|
56
|
+
# :nocov:
|
57
|
+
commands.concat(command_set.dup.commands) # NOTE: unreachable code at this moment
|
58
|
+
# :nocov:
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# @return [SmartCore::Container::DefinitionDSL::CommandSet]
|
64
|
+
#
|
65
|
+
# @api private
|
66
|
+
# @since 0.1.0
|
67
|
+
def dup
|
68
|
+
thread_safe do
|
69
|
+
self.class.new.tap do |duplicate|
|
70
|
+
commands.each do |command|
|
71
|
+
duplicate.add_command(command.dup)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
# @param block [Block]
|
80
|
+
# @return [Any]
|
81
|
+
#
|
82
|
+
# @api private
|
83
|
+
# @since 0.1.0
|
84
|
+
def thread_safe(&block)
|
85
|
+
@access_lock.thread_safe(&block)
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.1.0
|
5
|
+
class SmartCore::Container::DefinitionDSL::Commands::Base
|
6
|
+
class << self
|
7
|
+
# @param identifier [Boolean]
|
8
|
+
# @return [Boolean]
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
# @since 0.19.0
|
12
|
+
def inheritable=(identifier)
|
13
|
+
@inheritable = identifier
|
14
|
+
end
|
15
|
+
|
16
|
+
# @return [Boolean]
|
17
|
+
#
|
18
|
+
# @api private
|
19
|
+
# @since 0.19.0
|
20
|
+
def inheritable?
|
21
|
+
@inheritable
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return [Boolean]
|
25
|
+
#
|
26
|
+
# @api private
|
27
|
+
# @since 0.19.0
|
28
|
+
def inherited(child_klass)
|
29
|
+
child_klass.instance_variable_set(:@inheritable, true)
|
30
|
+
super
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# @param regsitry [SmartCore::Container::Registry]
|
35
|
+
# @return [void]
|
36
|
+
#
|
37
|
+
# @api private
|
38
|
+
# @since 0.1.0
|
39
|
+
def call(registry); end
|
40
|
+
|
41
|
+
# @return [Boolean]
|
42
|
+
#
|
43
|
+
# @api private
|
44
|
+
# @since 0.19.0
|
45
|
+
def inheritable?
|
46
|
+
self.class.inheritable?
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SmartCore::Container::DefinitionDSL::Commands::Definition
|
4
|
+
# @api private
|
5
|
+
# @since 0.1.0
|
6
|
+
class Compose < SmartCore::Container::DefinitionDSL::Commands::Base
|
7
|
+
# @since 0.1.0
|
8
|
+
self.inheritable = true
|
9
|
+
|
10
|
+
# @param container_klass [Class<SmartCore::Container>]
|
11
|
+
# @return [void]
|
12
|
+
#
|
13
|
+
# @api private
|
14
|
+
# @since 0.1.0
|
15
|
+
def initialize(container_klass)
|
16
|
+
raise(
|
17
|
+
SmartCore::ArgumentError,
|
18
|
+
'Container class should be a subtype of Quantum::Container'
|
19
|
+
) unless container_klass < SmartCore::Container
|
20
|
+
|
21
|
+
@container_klass = container_klass
|
22
|
+
end
|
23
|
+
|
24
|
+
# @param registry [SmartCore::Container::Registry]
|
25
|
+
# @return [void]
|
26
|
+
#
|
27
|
+
# @api private
|
28
|
+
# @since 0.1.0
|
29
|
+
def call(registry)
|
30
|
+
SmartCore::Container::RegistryBuilder.build_definitions(container_klass, registry)
|
31
|
+
end
|
32
|
+
|
33
|
+
# @return [SmartCore::Container::DefinitionDSL::Commands::Definition::Compose]
|
34
|
+
#
|
35
|
+
# @api private
|
36
|
+
# @since 0.1.0
|
37
|
+
def dup
|
38
|
+
self.class.new(container_klass)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
# @return [Class<SmartCore::Container>]
|
44
|
+
#
|
45
|
+
# @api private
|
46
|
+
# @since 0.1.0
|
47
|
+
attr_reader :container_klass
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SmartCore::Container::DefinitionDSL::Commands::Definition
|
4
|
+
# @api private
|
5
|
+
# @since 0.1.0
|
6
|
+
class Namespace < SmartCore::Container::DefinitionDSL::Commands::Base
|
7
|
+
# @since 0.1.0
|
8
|
+
self.inheritable = true
|
9
|
+
|
10
|
+
# @return [String]
|
11
|
+
#
|
12
|
+
# @api private
|
13
|
+
# @since 0.1.0
|
14
|
+
attr_reader :namespace_name
|
15
|
+
|
16
|
+
# @param namespace_name [String, Symbol]
|
17
|
+
# @param dependencies_definition [Proc]
|
18
|
+
# @return [void]
|
19
|
+
#
|
20
|
+
# @api private
|
21
|
+
# @since 0.1.0
|
22
|
+
def initialize(namespace_name, dependencies_definition)
|
23
|
+
SmartCore::Container::KeyGuard.indifferently_accessable_key(namespace_name).tap do |name|
|
24
|
+
@namespace_name = name
|
25
|
+
@dependencies_definition = dependencies_definition
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# @param registry [SmartCore::Container::Registry]
|
30
|
+
# @return [void]
|
31
|
+
#
|
32
|
+
# @api private
|
33
|
+
# @since 0.1.0
|
34
|
+
def call(registry)
|
35
|
+
registry.register_namespace(namespace_name, &dependencies_definition)
|
36
|
+
end
|
37
|
+
|
38
|
+
# @return [SmartCore::Container::DefinitionDSL::Commands::Definition::Namespace]
|
39
|
+
#
|
40
|
+
# @api private
|
41
|
+
# @since 0.1.0
|
42
|
+
def dup
|
43
|
+
self.class.new(namespace_name, dependencies_definition)
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
# @return [Proc]
|
49
|
+
#
|
50
|
+
# @api private
|
51
|
+
# @since 0.1.0
|
52
|
+
attr_reader :dependencies_definition
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SmartCore::Container::DefinitionDSL::Commands::Definition
|
4
|
+
# @api private
|
5
|
+
# @since 0.1.0
|
6
|
+
class Register < SmartCore::Container::DefinitionDSL::Commands::Base
|
7
|
+
# @since 0.1.0
|
8
|
+
self.inheritable = true
|
9
|
+
|
10
|
+
# @return [String]
|
11
|
+
#
|
12
|
+
# @api private
|
13
|
+
# @since 0.1.0
|
14
|
+
attr_reader :dependency_name
|
15
|
+
|
16
|
+
# @param dependency_name [String, Symbol]
|
17
|
+
# @param dependency_definition [Proc]
|
18
|
+
# @return [void]
|
19
|
+
#
|
20
|
+
# @api private
|
21
|
+
# @since 0.1.0
|
22
|
+
def initialize(dependency_name, dependency_definition)
|
23
|
+
SmartCore::Container::KeyGuard.indifferently_accessable_key(dependency_name).tap do |name|
|
24
|
+
@dependency_name = name
|
25
|
+
@dependency_definition = dependency_definition
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# @param registry [SmartCore::Container::Registry]
|
30
|
+
# @return [void]
|
31
|
+
#
|
32
|
+
# @api private
|
33
|
+
# @since 0.1.0
|
34
|
+
def call(registry)
|
35
|
+
registry.register_dependency(dependency_name, &dependency_definition)
|
36
|
+
end
|
37
|
+
|
38
|
+
# @return [SmartCore::Container::DefinitionDSL::Commands::Definition::Register]
|
39
|
+
#
|
40
|
+
# @api private
|
41
|
+
# @since 0.1.0
|
42
|
+
def dup
|
43
|
+
self.class.new(dependency_name, dependency_definition)
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
# @return [Proc]
|
49
|
+
#
|
50
|
+
# @api private
|
51
|
+
# @since 0.1.0
|
52
|
+
attr_reader :dependency_definition
|
53
|
+
end
|
54
|
+
end
|