scorpion-ioc 0.3.1 → 0.4.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 +4 -4
- data/.gitignore +2 -1
- data/.rspec +2 -1
- data/README.md +111 -44
- data/lib/scorpion/attribute.rb +0 -1
- data/lib/scorpion/attribute_set.rb +15 -7
- data/lib/scorpion/dependency/argument_dependency.rb +25 -0
- data/lib/scorpion/{prey/builder_prey.rb → dependency/builder_dependency.rb} +8 -8
- data/lib/scorpion/dependency/captured_dependency.rb +44 -0
- data/lib/scorpion/dependency/class_dependency.rb +25 -0
- data/lib/scorpion/dependency/module_dependency.rb +14 -0
- data/lib/scorpion/dependency.rb +137 -0
- data/lib/scorpion/dependency_map.rb +135 -0
- data/lib/scorpion/hunt.rb +158 -0
- data/lib/scorpion/hunter.rb +21 -20
- data/lib/scorpion/locale/en.yml +5 -1
- data/lib/scorpion/{king.rb → object.rb} +72 -53
- data/lib/scorpion/object_constructor.rb +55 -0
- data/lib/scorpion/rails/active_record/association.rb +65 -0
- data/lib/scorpion/rails/active_record/model.rb +28 -0
- data/lib/scorpion/rails/active_record/relation.rb +66 -0
- data/lib/scorpion/rails/active_record.rb +21 -0
- data/lib/scorpion/rails/controller.rb +22 -62
- data/lib/scorpion/rails/job.rb +30 -0
- data/lib/scorpion/rails/nest.rb +86 -0
- data/lib/scorpion/rails/railtie.rb +16 -0
- data/lib/scorpion/rails.rb +4 -0
- data/lib/scorpion/rspec/helper.rb +25 -0
- data/lib/scorpion/rspec.rb +17 -0
- data/lib/scorpion/stinger.rb +69 -0
- data/lib/scorpion/version.rb +1 -1
- data/lib/scorpion.rb +91 -44
- data/scorpion.gemspec +1 -1
- data/spec/internal/app/models/author.rb +17 -0
- data/spec/internal/app/models/todo.rb +14 -0
- data/spec/internal/db/schema.rb +12 -1
- data/spec/lib/scorpion/dependency/argument_dependency_spec.rb +18 -0
- data/spec/lib/scorpion/dependency/builder_dependency_spec.rb +41 -0
- data/spec/lib/scorpion/dependency/module_dependency_spec.rb +16 -0
- data/spec/lib/scorpion/dependency_map_spec.rb +108 -0
- data/spec/lib/scorpion/dependency_spec.rb +131 -0
- data/spec/lib/scorpion/hunt_spec.rb +93 -0
- data/spec/lib/scorpion/hunter_spec.rb +53 -14
- data/spec/lib/scorpion/object_constructor_spec.rb +49 -0
- data/spec/lib/scorpion/object_spec.rb +214 -0
- data/spec/lib/scorpion/rails/active_record/association_spec.rb +26 -0
- data/spec/lib/scorpion/rails/active_record/model_spec.rb +33 -0
- data/spec/lib/scorpion/rails/active_record/relation_spec.rb +72 -0
- data/spec/lib/scorpion/rails/controller_spec.rb +9 -9
- data/spec/lib/scorpion/rails/job_spec.rb +34 -0
- data/spec/lib/scorpion/rspec/helper_spec.rb +44 -0
- data/spec/lib/scorpion_spec.rb +0 -35
- data/spec/spec_helper.rb +1 -0
- metadata +54 -26
- data/lib/scorpion/hunting_map.rb +0 -139
- data/lib/scorpion/prey/captured_prey.rb +0 -44
- data/lib/scorpion/prey/class_prey.rb +0 -13
- data/lib/scorpion/prey/hunted_prey.rb +0 -14
- data/lib/scorpion/prey/module_prey.rb +0 -14
- data/lib/scorpion/prey.rb +0 -94
- data/spec/internal/db/combustion_test.sqlite +0 -0
- data/spec/lib/scorpion/hunting_map_spec.rb +0 -126
- data/spec/lib/scorpion/instance_spec.rb +0 -5
- data/spec/lib/scorpion/king_spec.rb +0 -198
- data/spec/lib/scorpion/prey/builder_prey_spec.rb +0 -42
- data/spec/lib/scorpion/prey/module_prey_spec.rb +0 -16
- data/spec/lib/scorpion/prey_spec.rb +0 -76
@@ -1,17 +1,18 @@
|
|
1
1
|
require 'scorpion/attribute_set'
|
2
2
|
|
3
3
|
module Scorpion
|
4
|
-
# Identifies objects that are
|
5
|
-
# {Scorpion#hunt hunted}
|
6
|
-
module
|
4
|
+
# Identifies objects that are injected by {Scorpion scorpions} that inject
|
5
|
+
# {Scorpion#hunt hunted} dependencies.
|
6
|
+
module Object
|
7
7
|
|
8
8
|
# ============================================================================
|
9
9
|
# @!group Attributes
|
10
10
|
#
|
11
11
|
|
12
12
|
# @!attribute
|
13
|
-
# @return [Scorpion] the scorpion used to hunt down
|
14
|
-
|
13
|
+
# @return [Scorpion] the scorpion used to hunt down dependencies.
|
14
|
+
attr_accessor :scorpion
|
15
|
+
private :scorpion=
|
15
16
|
|
16
17
|
# @!attribute
|
17
18
|
# @return [Scorpion::AttributeSet] the set of injected attributes and their
|
@@ -23,74 +24,68 @@ module Scorpion
|
|
23
24
|
#
|
24
25
|
# @!endgroup Attributes
|
25
26
|
|
26
|
-
#
|
27
|
+
# Injects one of the {#injected_attributes} into the object.
|
27
28
|
# @param [Scorpion::Attribute] attribute to be fed.
|
28
|
-
# @param [Object]
|
29
|
+
# @param [Object] dependency the value of the attribute
|
29
30
|
# @visibility private
|
30
31
|
#
|
31
|
-
# This method is used by the {#scorpion} to feed the
|
32
|
+
# This method is used by the {#scorpion} to feed the object. Do not call it
|
32
33
|
# directly.
|
33
|
-
def
|
34
|
-
send "#{ attribute.name }=",
|
34
|
+
def inject( attribute, dependency )
|
35
|
+
send "#{ attribute.name }=", dependency
|
35
36
|
end
|
36
37
|
|
37
|
-
# Crown the object as a
|
38
|
+
# Crown the object as a object and prepare it to be fed.
|
38
39
|
def self.crown( base )
|
39
|
-
base.extend Scorpion::
|
40
|
+
base.extend Scorpion::Object::ClassMethods
|
40
41
|
if base.is_a? Class
|
41
42
|
base.class_exec do
|
42
43
|
|
43
|
-
#
|
44
|
+
# Create a new instance of this class with all non-lazy dependencies
|
44
45
|
# satisfied.
|
45
|
-
# @param [
|
46
|
-
def self.spawn(
|
47
|
-
new( *args, &block ).tap do |
|
48
|
-
|
46
|
+
# @param [Hunt] hunt that this instance will be used to satisfy.
|
47
|
+
def self.spawn( hunt, *args, &block )
|
48
|
+
new( *args, &block ).tap do |object|
|
49
|
+
object.send :scorpion=, hunt.scorpion
|
50
|
+
|
49
51
|
# Go hunt for dependencies that are not lazy and initialize the
|
50
52
|
# references.
|
51
|
-
|
52
|
-
|
53
|
+
hunt.inject object
|
54
|
+
object.send :on_injected
|
53
55
|
end
|
54
56
|
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
base.subclasses.each do |sub|
|
61
|
+
crown( sub ) unless sub < Scorpion::Object
|
55
62
|
end
|
56
63
|
end
|
57
64
|
end
|
58
65
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
66
|
+
def self.included( base )
|
67
|
+
crown( base )
|
68
|
+
super
|
69
|
+
end
|
63
70
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
71
|
+
def self.prepended( base )
|
72
|
+
crown( base )
|
73
|
+
super
|
74
|
+
end
|
68
75
|
|
69
76
|
|
70
77
|
private
|
71
78
|
|
72
|
-
# Called after the
|
79
|
+
# Called after the object has been initialized and feed all its required
|
73
80
|
# dependencies. It should be used in place of #initialize when the
|
74
81
|
# constructor needs access to injected attributes.
|
75
|
-
def
|
76
|
-
end
|
77
|
-
|
78
|
-
# Convenience method to ask the {#scorpion} to hunt for an object.
|
79
|
-
# @see Scorpion#hunt
|
80
|
-
def hunt( contract, *args, &block )
|
81
|
-
scorpion.hunt contract, *args, &block
|
82
|
-
end
|
83
|
-
|
84
|
-
# Convenience method to ask the {#scorpion} to hunt for an object.
|
85
|
-
# @see Scorpion#hunt_by_traits
|
86
|
-
def hunt_by_traits( contract, traits, *args, &block )
|
87
|
-
scorpion.hunt_by_traits contract, *args, &block
|
82
|
+
def on_injected
|
88
83
|
end
|
89
84
|
|
90
85
|
# Feed dependencies from a hash into their associated attributes.
|
91
86
|
# @param [Hash] dependencies hash describing attributes to inject.
|
92
87
|
# @param [Boolean] overwrite existing attributes with values in in the hash.
|
93
|
-
def
|
88
|
+
def inject_from( dependencies, overwrite = false )
|
94
89
|
injected_attributes.each do |attr|
|
95
90
|
next unless dependencies.key? attr.name
|
96
91
|
|
@@ -101,11 +96,10 @@ module Scorpion
|
|
101
96
|
|
102
97
|
dependencies
|
103
98
|
end
|
104
|
-
alias_method :inject_from, :feast_on
|
105
99
|
|
106
100
|
# Injects dependenices from the hash and removes them from the hash.
|
107
|
-
# @see #
|
108
|
-
def
|
101
|
+
# @see #inject_from
|
102
|
+
def inject_from!( dependencies, overwrite = false )
|
109
103
|
injected_attributes.each do |attr|
|
110
104
|
next unless dependencies.key? attr.name
|
111
105
|
val = dependencies.delete( attr.name )
|
@@ -117,27 +111,52 @@ module Scorpion
|
|
117
111
|
|
118
112
|
dependencies
|
119
113
|
end
|
120
|
-
alias_method :inject_from!, :feast_on!
|
121
114
|
|
122
115
|
module ClassMethods
|
123
116
|
|
117
|
+
# Define an initializer that accepts injections.
|
118
|
+
# @param [Hash] arguments to accept in the initializer.
|
119
|
+
# @yield to initialize itself.
|
120
|
+
def initialize( arguments, &block )
|
121
|
+
Scorpion::ObjectConstructor.new( self, arguments, &block ).define
|
122
|
+
end
|
123
|
+
|
124
124
|
# Tells a {Scorpion} what to inject into the class when it is constructed
|
125
125
|
# @return [nil]
|
126
126
|
# @see AttributeSet#define
|
127
|
-
def
|
127
|
+
def depend_on( &block )
|
128
128
|
injected_attributes.define &block
|
129
129
|
build_injected_attributes
|
130
130
|
end
|
131
|
-
alias_method :inject, :
|
132
|
-
alias_method :depend_on, :
|
131
|
+
alias_method :inject, :depend_on
|
132
|
+
alias_method :depend_on, :depend_on
|
133
|
+
|
134
|
+
# Define a single dependency and accessor.
|
135
|
+
# @param [Symbol] name of the dependency.
|
136
|
+
# @param [Class,Module,Symbol] contract describing the desired behavior of the dependency.
|
137
|
+
# @param [Array<Symbol>] traits found on the {Dependency}.
|
138
|
+
def attr_dependency( name, contract, *traits, &block )
|
139
|
+
attr = injected_attributes.define_attribute name, contract, *traits, &block
|
140
|
+
build_injected_attribute attr
|
141
|
+
set_injected_attribute_visibility attr
|
142
|
+
end
|
133
143
|
|
134
144
|
# @!attribute
|
135
145
|
# @return [Scorpion::AttributeSet] the set of injected attriutes.
|
136
146
|
def injected_attributes
|
137
147
|
@injected_attributes ||= begin
|
138
|
-
|
139
|
-
|
140
|
-
|
148
|
+
attrs = AttributeSet.new
|
149
|
+
attrs.inherit! superclass.injected_attributes if superclass.respond_to? :injected_attributes
|
150
|
+
attrs
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# @!attribute
|
155
|
+
# @return [Scorpion::AttributeSet] the set of injected attriutes.
|
156
|
+
def initializer_injections
|
157
|
+
@initializer_injections ||= begin
|
158
|
+
attrs = AttributeSet.new
|
159
|
+
attrs
|
141
160
|
end
|
142
161
|
end
|
143
162
|
|
@@ -155,7 +174,7 @@ module Scorpion
|
|
155
174
|
def #{ attr.name }
|
156
175
|
@#{ attr.name } ||= begin
|
157
176
|
attr = injected_attributes[ :#{ attr.name } ]
|
158
|
-
scorpion.
|
177
|
+
scorpion.fetch( attr.contract, attr.traits )
|
159
178
|
end
|
160
179
|
end
|
161
180
|
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Scorpion
|
2
|
+
# Builds an injectable constructor for a Scorpion::Object.
|
3
|
+
class ObjectConstructor
|
4
|
+
|
5
|
+
def initialize( base, arguments, &block )
|
6
|
+
@base = base
|
7
|
+
@arguments = arguments
|
8
|
+
@block = block
|
9
|
+
end
|
10
|
+
|
11
|
+
def define
|
12
|
+
@signature = []
|
13
|
+
@body = ""
|
14
|
+
|
15
|
+
build_signature
|
16
|
+
build_body
|
17
|
+
|
18
|
+
add_initialize_block
|
19
|
+
assemble
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
attr_reader :base, :arguments, :block, :body, :signature
|
24
|
+
|
25
|
+
def build_signature
|
26
|
+
arguments.each do |key,expectation|
|
27
|
+
signature << key
|
28
|
+
|
29
|
+
base.initializer_injections.define_attribute key, *Array( expectation )
|
30
|
+
base.attr_dependency key, *Array( expectation )
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def build_body
|
35
|
+
arguments.each do |key,expectation|
|
36
|
+
body << "@#{ key } = #{ key };"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def add_initialize_block
|
41
|
+
if block
|
42
|
+
body << "__initialize_with_block( &block )"
|
43
|
+
base.send :define_method, :__initialize_with_block, &block
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def assemble
|
48
|
+
base.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
49
|
+
def initialize( #{ signature.join( ', ' ) }, &block )
|
50
|
+
#{ body }
|
51
|
+
end
|
52
|
+
RUBY
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Scorpion
|
2
|
+
module Rails
|
3
|
+
module ActiveRecord
|
4
|
+
|
5
|
+
# Adds dependency injection to ActiveRecord::Base model associations.
|
6
|
+
module Association
|
7
|
+
include Scorpion::Stinger
|
8
|
+
|
9
|
+
# ============================================================================
|
10
|
+
# @!group Attributes
|
11
|
+
#
|
12
|
+
|
13
|
+
# @!attribute
|
14
|
+
# @return [Scorpion] the scorpion serving the association.
|
15
|
+
attr_accessor :scorpion
|
16
|
+
def scorpion
|
17
|
+
@scorpion || owner.scorpion
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
# @!endgroup Attributes
|
22
|
+
|
23
|
+
|
24
|
+
# Make sure we override the methods of child classes as well.
|
25
|
+
def self.prepended( base )
|
26
|
+
infect base
|
27
|
+
super
|
28
|
+
end
|
29
|
+
|
30
|
+
# Propagate the module inheritance to all derived classes so that we can
|
31
|
+
# always overlay our interception methods on the top-most overriden
|
32
|
+
# method.
|
33
|
+
def self.infect( klass )
|
34
|
+
klass.class_exec do
|
35
|
+
def self.inherited( from )
|
36
|
+
Scorpion::Rails::ActiveRecord::Association.infect( from )
|
37
|
+
|
38
|
+
super
|
39
|
+
end
|
40
|
+
end
|
41
|
+
overlay( klass )
|
42
|
+
end
|
43
|
+
|
44
|
+
# Overlay interception methods on the klass.
|
45
|
+
def self.overlay( klass )
|
46
|
+
[ :load_target, :target, :reader, :writer, :scope ].each do |method|
|
47
|
+
next unless klass.instance_methods.include? method
|
48
|
+
|
49
|
+
mod = Module.new do
|
50
|
+
module_eval <<-EOS, __FILE__, __LINE__ + 1
|
51
|
+
def #{ method }( *args, &block )
|
52
|
+
sting! super
|
53
|
+
end
|
54
|
+
EOS
|
55
|
+
end
|
56
|
+
|
57
|
+
klass.prepend mod
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Scorpion
|
2
|
+
module Rails
|
3
|
+
module ActiveRecord
|
4
|
+
|
5
|
+
# Adds dependency injection to ActiveRecord::Base models.
|
6
|
+
module Model
|
7
|
+
include Scorpion::Stinger
|
8
|
+
|
9
|
+
def self.prepended( base )
|
10
|
+
# Setup dependency injection
|
11
|
+
base.send :include, Scorpion::Object
|
12
|
+
base.send :extend, ClassMethods
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
module ClassMethods
|
17
|
+
delegate :with_scorpion, to: :all
|
18
|
+
end
|
19
|
+
|
20
|
+
def association( *args, &block )
|
21
|
+
sting! super
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module Scorpion
|
2
|
+
module Rails
|
3
|
+
module ActiveRecord
|
4
|
+
|
5
|
+
# Make sure that all models return by the relation inherit the relation's
|
6
|
+
# scorpion.
|
7
|
+
module Relation
|
8
|
+
include Scorpion::Stinger
|
9
|
+
|
10
|
+
# ============================================================================
|
11
|
+
# @!group Attributes
|
12
|
+
#
|
13
|
+
|
14
|
+
# @!attribute
|
15
|
+
# @return [Scorpion] the scorpion serving the relation.
|
16
|
+
attr_accessor :scorpion
|
17
|
+
|
18
|
+
#
|
19
|
+
# @!endgroup Attributes
|
20
|
+
|
21
|
+
# Elect to use a specific scorpion for all further operations in the
|
22
|
+
# chain.
|
23
|
+
#
|
24
|
+
# @example
|
25
|
+
#
|
26
|
+
# User.all.with_scorpion( scorpion ).where( ... )
|
27
|
+
# User.with_scorpion( scorpion ).where( ... )
|
28
|
+
def with_scorpion( scorpion )
|
29
|
+
spawn.tap do |other|
|
30
|
+
other.scorpion = scorpion
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
# from ActiveRecord::Relation
|
36
|
+
[ :new, :build, :create, :create! ].each do |method|
|
37
|
+
class_eval <<-EOS, __FILE__, __LINE__ + 1
|
38
|
+
def #{ method }( *args, &block )
|
39
|
+
super *args do |*block_args|
|
40
|
+
sting!( block_args )
|
41
|
+
yield *block_args if block_given?
|
42
|
+
end
|
43
|
+
end
|
44
|
+
EOS
|
45
|
+
end
|
46
|
+
|
47
|
+
# from ActiveRecord::SpawnMethods
|
48
|
+
def spawn
|
49
|
+
sting!( super )
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
# from ActiveRecord::Relation
|
54
|
+
def exec_queries( *args, &block )
|
55
|
+
sting!( super )
|
56
|
+
end
|
57
|
+
|
58
|
+
# from ActiveRecord::SpawnMethods
|
59
|
+
def relation_with( *args )
|
60
|
+
sting!( super )
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Scorpion
|
2
|
+
module Rails
|
3
|
+
module ActiveRecord
|
4
|
+
require 'scorpion/rails/active_record/model'
|
5
|
+
require 'scorpion/rails/active_record/relation'
|
6
|
+
require 'scorpion/rails/active_record/association'
|
7
|
+
|
8
|
+
# Setup scorpion support for activerecord
|
9
|
+
def self.install!
|
10
|
+
return unless defined? ::ActiveRecord
|
11
|
+
|
12
|
+
::ActiveRecord::Base.send :prepend, Scorpion::Rails::ActiveRecord::Model
|
13
|
+
::ActiveRecord::Relation.send :prepend, Scorpion::Rails::ActiveRecord::Relation
|
14
|
+
::ActiveRecord::Associations::Association.send :prepend, Scorpion::Rails::ActiveRecord::Association
|
15
|
+
|
16
|
+
# TODO extend Scorpion::Hunter to support AR
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
@@ -1,89 +1,49 @@
|
|
1
1
|
require 'scorpion/nest'
|
2
|
-
require 'active_support/core_ext/class/attribute'
|
3
2
|
|
4
3
|
module Scorpion
|
5
4
|
module Rails
|
6
|
-
# Adds a scorpion nest to rails controllers to automatically support
|
7
|
-
# injection into rails controllers.
|
8
|
-
module Controller
|
9
|
-
|
10
|
-
# ============================================================================
|
11
|
-
# @!group Attributes
|
12
|
-
#
|
13
|
-
|
14
|
-
# @!attribute
|
15
|
-
# @return [Scorpion] the scorpion used to fetch dependencies.
|
16
|
-
attr_reader :scorpion
|
17
|
-
private :scorpion
|
18
5
|
|
19
|
-
|
20
|
-
|
21
|
-
def nest
|
22
|
-
self.class.nest
|
23
|
-
end
|
24
|
-
private :nest
|
6
|
+
# Adds a scorpion nest to support injection into rails controllers.
|
7
|
+
module Controller
|
25
8
|
|
26
|
-
|
27
|
-
# @!endgroup Attributes
|
9
|
+
ENV_KEY = 'scorpion.instance'.freeze
|
28
10
|
|
11
|
+
def scorpion
|
12
|
+
env[ENV_KEY]
|
13
|
+
end
|
29
14
|
|
30
15
|
def self.included( base )
|
31
16
|
# Setup dependency injection
|
32
|
-
base.send :include, Scorpion::
|
33
|
-
base.
|
34
|
-
|
35
|
-
# @!attribute [rw]
|
36
|
-
# @return [Scorpion::Nest] the singleton nest used by controllers.
|
37
|
-
base.class_attribute :nest_instance
|
38
|
-
base.class_exec do
|
39
|
-
|
40
|
-
# @!attribute
|
41
|
-
# @return [Scorpion::Nest] the nest used to conceive scorpions to
|
42
|
-
# hunt for objects on each request.
|
43
|
-
def self.nest
|
44
|
-
nest_instance
|
45
|
-
end
|
46
|
-
def self.nest=( value )
|
47
|
-
nest_instance.destroy if nest_instance
|
48
|
-
self.nest_instance = value
|
49
|
-
end
|
50
|
-
|
51
|
-
# Prepare the nest for conceiving scorpions.
|
52
|
-
# @see HuntingMap#chart
|
53
|
-
def self.scorpion_nest( &block )
|
54
|
-
nest.prepare &block
|
55
|
-
end
|
56
|
-
end
|
57
|
-
base.nest ||= Scorpion.instance.build_nest
|
58
|
-
|
17
|
+
base.send :include, Scorpion::Rails::Nest
|
18
|
+
base.around_filter :with_scorpion
|
59
19
|
super
|
60
20
|
end
|
61
21
|
|
62
22
|
private
|
63
23
|
|
64
24
|
# Fetch a scorpion and feed the controller it's dependencies
|
65
|
-
def
|
66
|
-
|
25
|
+
def prepare_scorpion( scorpion )
|
26
|
+
scorpion.prepare do |hunter|
|
27
|
+
# Allow dependencies to access the controller
|
28
|
+
hunter.hunt_for AbstractController::Base, return: self
|
67
29
|
|
68
|
-
@scorpion.prepare do |hunter|
|
69
|
-
hunter.hunt_for AbstractController::Base do
|
70
|
-
self
|
71
|
-
end
|
72
30
|
# Allow dependencies to access the current request/response
|
73
|
-
hunter.hunt_for ActionDispatch::Request do |
|
74
|
-
|
31
|
+
hunter.hunt_for ActionDispatch::Request do |hunt|
|
32
|
+
hunt.fetch( AbstractController::Base ).request
|
75
33
|
end
|
76
|
-
hunter.hunt_for ActionDispatch::Response do |
|
77
|
-
|
34
|
+
hunter.hunt_for ActionDispatch::Response do |hunt|
|
35
|
+
hunt.fetch( AbstractController::Base ).response
|
78
36
|
end
|
79
37
|
end
|
38
|
+
end
|
80
39
|
|
81
|
-
|
40
|
+
def assign_scorpion( scorpion )
|
41
|
+
env[ENV_KEY] = scorpion
|
42
|
+
end
|
82
43
|
|
83
|
-
|
84
|
-
ensure
|
85
|
-
@scorpion = nil
|
44
|
+
def free_scorpion
|
86
45
|
end
|
46
|
+
|
87
47
|
end
|
88
48
|
end
|
89
49
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'scorpion/nest'
|
2
|
+
|
3
|
+
module Scorpion
|
4
|
+
module Rails
|
5
|
+
|
6
|
+
# Adds a scorpion nest to support injection into rails background worker jobs.
|
7
|
+
module Job
|
8
|
+
|
9
|
+
def self.included( base )
|
10
|
+
# Setup dependency injection
|
11
|
+
base.send :include, Scorpion::Rails::Nest
|
12
|
+
base.send :around_perform do |job, block|
|
13
|
+
job.with_scorpion &block
|
14
|
+
end
|
15
|
+
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def prepare_scorpion( scorpion )
|
22
|
+
scorpion.prepare do |hunter|
|
23
|
+
hunter.hunt_for ActiveJob::Base do
|
24
|
+
self
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'scorpion/nest'
|
2
|
+
require 'active_support/core_ext/class/attribute'
|
3
|
+
|
4
|
+
module Scorpion
|
5
|
+
module Rails
|
6
|
+
# Handles building a scorpion to handle a single request and populating
|
7
|
+
# all the dependencies automatically.
|
8
|
+
module Nest
|
9
|
+
|
10
|
+
# ============================================================================
|
11
|
+
# @!group Attributes
|
12
|
+
#
|
13
|
+
|
14
|
+
# @!attribute
|
15
|
+
# @return [Scorpion] the scorpion used to fetch dependencies.
|
16
|
+
attr_reader :scorpion
|
17
|
+
private :scorpion
|
18
|
+
|
19
|
+
# @!attribute
|
20
|
+
# @return [Scorpion::Nest] the nest used to conceive scorpions.
|
21
|
+
def nest
|
22
|
+
self.class.nest
|
23
|
+
end
|
24
|
+
private :nest
|
25
|
+
|
26
|
+
#
|
27
|
+
# @!endgroup Attributes
|
28
|
+
|
29
|
+
def self.included( base )
|
30
|
+
# Setup dependency injection
|
31
|
+
base.send :include, Scorpion::Object
|
32
|
+
|
33
|
+
# @!attribute [rw]
|
34
|
+
# @return [Scorpion::Nest] the singleton nest used by controllers.
|
35
|
+
base.class_attribute :nest_instance
|
36
|
+
base.class_exec do
|
37
|
+
|
38
|
+
# @!attribute
|
39
|
+
# @return [Scorpion::Nest] the nest used to conceive scorpions to
|
40
|
+
# hunt for objects on each request.
|
41
|
+
def self.nest
|
42
|
+
nest_instance
|
43
|
+
end
|
44
|
+
def self.nest=( value )
|
45
|
+
nest_instance.destroy if nest_instance
|
46
|
+
self.nest_instance = value
|
47
|
+
end
|
48
|
+
|
49
|
+
# Prepare the nest for conceiving scorpions.
|
50
|
+
# @see DependencyMap#chart
|
51
|
+
def self.scorpion_nest( &block )
|
52
|
+
nest.prepare &block
|
53
|
+
end
|
54
|
+
end
|
55
|
+
base.nest ||= Scorpion.instance.build_nest
|
56
|
+
|
57
|
+
super
|
58
|
+
end
|
59
|
+
|
60
|
+
# Fetch a scorpion and feed the controller it's dependencies, then yield
|
61
|
+
# to perform the action within the context of that scorpion.
|
62
|
+
def with_scorpion( &block )
|
63
|
+
assign_scorpion( nest.conceive )
|
64
|
+
|
65
|
+
prepare_scorpion( @scorpion ) if respond_to?( :prepare_scorpion, true )
|
66
|
+
|
67
|
+
hunt = Scorpion::Hunt.new @scorpion, nil, nil
|
68
|
+
hunt.inject self
|
69
|
+
|
70
|
+
yield
|
71
|
+
ensure
|
72
|
+
free_scorpion
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def assign_scorpion( scorpion )
|
78
|
+
@scorpion = scorpion
|
79
|
+
end
|
80
|
+
|
81
|
+
def free_scorpion
|
82
|
+
@scorpion = nil
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rails/railtie'
|
2
|
+
|
3
|
+
module Scorpion
|
4
|
+
module Rails
|
5
|
+
class Railtie < ::Rails::Railtie
|
6
|
+
|
7
|
+
initializer "scorpion.configure" do |app|
|
8
|
+
::ActionController::Base.send :include, Scorpion::Rails::Controller
|
9
|
+
::ActiveJob::Base.send :include, Scorpion::Rails::Job
|
10
|
+
|
11
|
+
::Scorpion::Rails::ActiveRecord.install!
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|