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