smart_inject 0.0.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/lib/smart_inject.rb +105 -0
- metadata +48 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 4d6bdfd2e40cc84906ab12e6e37eb7ae2db54be98ca5a18106a7d4de7cc47545
|
4
|
+
data.tar.gz: 757349ae540f1ffcfb5857814a79c8ed21906654790a81ed854b6f21fdb60b24
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9dfe7e53fd252c9bd8f8c162422aac075106bcbc4275afae916b184e86935a00ec250c30e5e8c737f1d5d13c3b04aac91a5208b39c053cbc4a335d67bb9cbad3
|
7
|
+
data.tar.gz: 6d60f6f4a659038127c6c2888ecb354667521f49ae160f9e9a285e910b3e3f45d16f07256f0912b4bca0c9c80e9255424c5d620139034b75c34900ad1db3caad
|
data/lib/smart_inject.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# SmartInject - Made DI deadly simple
|
5
|
+
#
|
6
|
+
# SmartInject is a minimalist, flexible and efficient dependency injection for
|
7
|
+
# Ruby.
|
8
|
+
#
|
9
|
+
# Here, no DSL, no complex machinery, no dynamic change on the object model.
|
10
|
+
# This is just a lightweight class that bring you DI using constructor, one of
|
11
|
+
# the most used method for DI. You can use it without constraint on your design.
|
12
|
+
#
|
13
|
+
# SmartInject can be used in isolation within your Gem just by applying standard
|
14
|
+
# ruby code: extend a class from SmartInject, and this is your new DI container.
|
15
|
+
#
|
16
|
+
# Feel free to see the code of SmartInject (very short), get the gem or
|
17
|
+
# copy-past the SmartInject class file into your project... There is no external
|
18
|
+
# dependency.
|
19
|
+
#
|
20
|
+
# SmartInject is intented to be under your control. No magic here.
|
21
|
+
#
|
22
|
+
class SmartInject
|
23
|
+
class SmartInjectError < StandardError; end
|
24
|
+
|
25
|
+
class ContainerError < SmartInjectError; end
|
26
|
+
|
27
|
+
class InjectionError < SmartInjectError; end
|
28
|
+
|
29
|
+
class << self
|
30
|
+
def services
|
31
|
+
@services ||= {}
|
32
|
+
end
|
33
|
+
|
34
|
+
def [](klass)
|
35
|
+
klass_name = klass.to_s
|
36
|
+
|
37
|
+
if @share_injections
|
38
|
+
service = running[klass_name]
|
39
|
+
return service if service
|
40
|
+
end
|
41
|
+
|
42
|
+
service = services.fetch(klass_name) { raise InjectionError, "service #{klass_name} unknown. Try to add #{name}.add(self) at the begining of #{klass_name} class." }
|
43
|
+
try_instanciate(service).tap do |instance|
|
44
|
+
running[klass_name] = instance if @share_injections
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def remap(looked_klass, injected_klass)
|
49
|
+
(raise ContainerError, "the #{name} container is already started. No remap allowed") if frozen?
|
50
|
+
(raise ContainerError, "first argument must be a class. Found: #{looked_klass}") unless looked_klass.instance_of?(Class)
|
51
|
+
(raise ContainerError, "second argument must be a class. Found: #{injected_klass}") unless injected_klass.instance_of?(Class)
|
52
|
+
|
53
|
+
services[looked_klass.name] = injected_klass
|
54
|
+
self
|
55
|
+
end
|
56
|
+
|
57
|
+
def add(klass, &block)
|
58
|
+
(raise ContainerError, "the #{name} container is already started. No add allowed") if frozen?
|
59
|
+
(raise ContainerError, "first argument must be a class. Found: #{klass}") unless klass.instance_of?(Class)
|
60
|
+
|
61
|
+
services[klass.name] = block || klass
|
62
|
+
running.delete(klass.name)
|
63
|
+
self
|
64
|
+
end
|
65
|
+
|
66
|
+
def start_container!
|
67
|
+
return self if frozen?
|
68
|
+
return freeze if @share_injections
|
69
|
+
|
70
|
+
services.each do |(klass_name, service)|
|
71
|
+
next if running[klass_name]
|
72
|
+
|
73
|
+
try_instanciate(service).tap { |instance| running[klass_name] = instance }
|
74
|
+
end
|
75
|
+
freeze
|
76
|
+
end
|
77
|
+
|
78
|
+
def share_injections
|
79
|
+
(raise ContainerError, "the #{name} container is already started. No share_injections allowed") if frozen?
|
80
|
+
|
81
|
+
@share_injections = true
|
82
|
+
self
|
83
|
+
end
|
84
|
+
|
85
|
+
def share_injections?
|
86
|
+
!!(@share_injections)
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
def running
|
92
|
+
@running ||= {}
|
93
|
+
end
|
94
|
+
|
95
|
+
def try_instanciate(klass_or_callable)
|
96
|
+
if klass_or_callable.is_a?(Proc)
|
97
|
+
klass_or_callable.call
|
98
|
+
else
|
99
|
+
klass_or_callable.new
|
100
|
+
end
|
101
|
+
rescue ArgumentError
|
102
|
+
raise InjectionError, "automatic injection can't be done: all arguments of the constructor are not subject to injection. Try to #{name}.add(#{klass_or_callable}) { <BLOC TO INSTANTIATE YOUR CLASS WITH ARGUMENTS (OUTSIDE OF THOSE INJECTED)> }"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
metadata
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: smart_inject
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ludovic de Luna
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-06-03 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: |
|
14
|
+
SmartInject is a minimalist, flexible and efficient dependency injection
|
15
|
+
for Ruby based on constructor injection, one of the most used method for
|
16
|
+
DI.
|
17
|
+
|
18
|
+
SmartInject is intented to be under your control. No magic here.
|
19
|
+
email: ludovic@deluna.fr
|
20
|
+
executables: []
|
21
|
+
extensions: []
|
22
|
+
extra_rdoc_files: []
|
23
|
+
files:
|
24
|
+
- lib/smart_inject.rb
|
25
|
+
homepage: https://rubygems.org/gems/smart_inject
|
26
|
+
licenses:
|
27
|
+
- MIT
|
28
|
+
metadata: {}
|
29
|
+
post_install_message:
|
30
|
+
rdoc_options: []
|
31
|
+
require_paths:
|
32
|
+
- lib
|
33
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
34
|
+
requirements:
|
35
|
+
- - ">="
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '2.5'
|
38
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
requirements: []
|
44
|
+
rubygems_version: 3.2.22
|
45
|
+
signing_key:
|
46
|
+
specification_version: 4
|
47
|
+
summary: Made DI deadly simple
|
48
|
+
test_files: []
|