corindon 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: a434327fdcd84d86831c646b72ff25fc3cd31b039372aae53ec049ce7ecc7f0b
4
- data.tar.gz: 84f16cdae405704f1332e10b15e4e406d735c051d01d1dfd23b0cbace986e68b
3
+ metadata.gz: 3d803035372216a30b75af02572aac4a1978e1f0d687c6425d26074913abfb1f
4
+ data.tar.gz: '007096e0f7cfa51fc6b85d1b4a4c63ef920b13a6f6f8bd638313b9c7ddd4743b'
5
5
  SHA512:
6
- metadata.gz: b819f64edf34893ec6af428914c3b41f70b1f7718a2c0acd88c6ce5d5b51664a6c5d866131c20161ebf4d34180d1e011a018ffc88b27038128982d094461e479
7
- data.tar.gz: 9b1c58294f04fd4612c889ff537c2343c2bded16a44c30b0e8af9b15443e28caef5683f0ec0734624786e03aa88a5a942c61b9ef36efa0888ec7515c89fbd772
6
+ metadata.gz: 5a9fdc84c38dd60b28bedc5469305c6cbaaf52a3291f140494b3aab2f010a717afa54e797681aeb140f99700fef50688ead340301acf55e8322701f0048edae1
7
+ data.tar.gz: b616cdbbefa1d2f84104082bb28deea30af5bdced64600a0d28ccd59f595928ed270de394f38a5c8040159973298213836315c74b2543d6828b292af0b1bc806
@@ -15,8 +15,10 @@ Gem::Specification.new do |s|
15
15
 
16
16
  s.required_ruby_version = '>= 2.6.0'
17
17
 
18
+ s.add_dependency 'semantic', '~> 1.6'
18
19
  s.add_dependency 'zeitwerk', '~> 2.3'
19
20
 
21
+ s.add_development_dependency 'bundler'
20
22
  s.add_development_dependency 'minitest', '~> 5.14'
21
23
  s.add_development_dependency 'rake', '~> 13.0'
22
24
  end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Corindon
4
+ module DependencyInjection
5
+ class Container
6
+ using Ext::Something
7
+
8
+ attr_reader :definitions
9
+ attr_reader :injector
10
+ attr_reader :services
11
+
12
+ def initialize
13
+ @services = {}
14
+ @definitions = {}
15
+
16
+ @injector = Injector.new(container: self)
17
+ end
18
+
19
+ # @param [Class] klass
20
+ def add_definition(klass, &block)
21
+ @definitions[to_id(klass)] = if injectable?(klass)
22
+ klass.definition
23
+ elsif block.sth?
24
+ Dsl.new(klass).exec(&block)
25
+ else
26
+ Definition.new(klass)
27
+ end
28
+ end
29
+
30
+ # @param [Class, #to_s] key
31
+ # @return [Boolean]
32
+ def has?(key)
33
+ @definitions.key?(to_id(key))
34
+ end
35
+
36
+ # @param [Class, #to_s] key
37
+ # @return [Object]
38
+ def get(key)
39
+ id = to_id(key)
40
+
41
+ if has?(key)
42
+ services.fetch(id) { build_service(id) }
43
+ elsif injectable?(key)
44
+ key.definition.build(injector)
45
+ else
46
+ raise StandardError.new("No service #{id}")
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ def build_service(id)
53
+ @definitions.fetch(id).build(injector).tap do |service|
54
+ @services[id] = service
55
+ end
56
+ end
57
+
58
+ def injectable?(klass)
59
+ klass.ancestors.include?(Injectable)
60
+ end
61
+
62
+ # @param [Class, #to_s] key
63
+ def to_id(key)
64
+ if key.is_a?(Class)
65
+ key.name
66
+ else
67
+ key.to_s
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'semantic'
4
+
5
+ module Corindon
6
+ module DependencyInjection
7
+ class Definition
8
+ attr_reader :klass
9
+ attr_reader :args
10
+ attr_reader :kwargs
11
+ attr_reader :calls
12
+
13
+ def initialize(klass, args = [], kwargs = {}, calls = [])
14
+ @klass = klass
15
+ @args = args
16
+ @kwargs = kwargs
17
+ @calls = calls
18
+ end
19
+
20
+ # @param [Injector] injector
21
+ # # @return [Object]
22
+ def build(injector)
23
+ object = do_call(klass, :new, *injector.resolve(args, kwargs))
24
+
25
+ calls.each do |(call, call_args, call_kwargs)|
26
+ do_call(object, call, *injector.resolve(call_args, call_kwargs))
27
+ end
28
+
29
+ object
30
+ end
31
+
32
+ private
33
+
34
+ if ::Semantic::Version.new(RUBY_VERSION).satisfies?(">= 2.7.0")
35
+ def do_call(obj, method, args, kwargs)
36
+ obj.send(method, *args, **kwargs)
37
+ end
38
+ else
39
+ def do_call(obj, method, args, kwargs)
40
+ if args.empty? && kwargs.empty?
41
+ obj.send(method)
42
+ elsif args.empty?
43
+ obj.send(method, **kwargs)
44
+ elsif kwargs.empty?
45
+ obj.send(method, *args)
46
+ else
47
+ obj.send(method, *args, **kwargs)
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Corindon
4
+ module DependencyInjection
5
+ class Dsl
6
+ # @param [Class] klass
7
+ def initialize(klass)
8
+ @klass = klass
9
+ @args = []
10
+ @kwargs = {}
11
+ @calls = []
12
+ end
13
+
14
+ # @return [Definition]
15
+ def exec(&block)
16
+ instance_exec(&block)
17
+
18
+ Definition.new(@klass, @args, @kwargs, @calls)
19
+ end
20
+
21
+ def args(*arguments, **kv_arguments)
22
+ @args = arguments
23
+ @kwargs = kv_arguments
24
+ end
25
+
26
+ # @param [String] name
27
+ def call(name, *arguments, **kv_arguments)
28
+ @calls << [name, arguments, kv_arguments]
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Corindon
4
+ module DependencyInjection
5
+ module Injectable
6
+ def definition
7
+ Definition.new(self)
8
+ end
9
+
10
+ refine Class do
11
+ def injectable(*args, **kwargs, &block)
12
+ include Injectable
13
+
14
+ define_singleton_method :definition do
15
+ if block.nil?
16
+ Definition.new(self, args, kwargs, [])
17
+ else
18
+ Dsl.new(self).exec(&block)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Corindon
4
+ module DependencyInjection
5
+ class Injector
6
+ attr_reader :container
7
+
8
+ # @param [Container] container
9
+ def initialize(container:)
10
+ @container = container
11
+ end
12
+
13
+ # @return [Array{Array, Hash}]
14
+ def resolve(args, kwargs)
15
+ [resolve_value(args), resolve_value(kwargs)]
16
+ end
17
+
18
+ private
19
+
20
+ def resolve_value(value)
21
+ if value.is_a?(Array)
22
+ value.map(&method(:resolve_value))
23
+ elsif value.is_a?(Hash)
24
+ value.transform_values(&method(:resolve_value))
25
+ else
26
+ container.get(value)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Corindon
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: corindon
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
  - Rémi Piotaix
@@ -10,6 +10,20 @@ bindir: bin
10
10
  cert_chain: []
11
11
  date: 2020-09-06 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: semantic
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: zeitwerk
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -24,6 +38,20 @@ dependencies:
24
38
  - - "~>"
25
39
  - !ruby/object:Gem::Version
26
40
  version: '2.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
27
55
  - !ruby/object:Gem::Dependency
28
56
  name: minitest
29
57
  requirement: !ruby/object:Gem::Requirement
@@ -60,6 +88,11 @@ extra_rdoc_files: []
60
88
  files:
61
89
  - corindon.gemspec
62
90
  - lib/corindon.rb
91
+ - lib/corindon/dependency_injection/container.rb
92
+ - lib/corindon/dependency_injection/definition.rb
93
+ - lib/corindon/dependency_injection/dsl.rb
94
+ - lib/corindon/dependency_injection/injectable.rb
95
+ - lib/corindon/dependency_injection/injector.rb
63
96
  - lib/corindon/ext/something.rb
64
97
  - lib/corindon/version.rb
65
98
  homepage: https://gitlab.com/piotaixr/corindon