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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d9f9e729630d83f9132e46118f0a74a9bcc9946f
|
4
|
+
data.tar.gz: 40a34e024069aaf348ce03b37065d83098920e40
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 32a04845861b9ea89cd5dcd19c667a0a339a424513c7b610f9909c3995e37d45707f837f3b10c8ce2d844ef12698268ffaa50c2afde083f54cd3161c4877d792
|
7
|
+
data.tar.gz: 435e3fbc679d5ad65fc7f5d2cce00adb802b5c73b91d1995f15c9012f6b0a8a99cee97c70cf7907b391d71fe831b8f8b38958249ef89ced063a9b0654a5f2f2e
|
data/.gitignore
CHANGED
data/.rspec
CHANGED
data/README.md
CHANGED
@@ -8,15 +8,13 @@
|
|
8
8
|
|
9
9
|
Add IoC to rails with minimal fuss and ceremony.
|
10
10
|
|
11
|
-
<!--
|
12
|
-
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
13
|
-
|
11
|
+
<!-- MarkdownTOC depth=4 -->
|
14
12
|
|
15
13
|
- [Dependency Injection](#dependency-injection)
|
16
14
|
- [Why might you _Want_ a DI FRamework?](#why-might-you-_want_-a-di-framework)
|
17
15
|
- [Using a Framework...like Scorpion](#using-a-frameworklike-scorpion)
|
18
16
|
- [Using Scorpion](#using-scorpion)
|
19
|
-
- [
|
17
|
+
- [Objects](#objects)
|
20
18
|
- [Configuration](#configuration)
|
21
19
|
- [Classes](#classes)
|
22
20
|
- [Modules](#modules)
|
@@ -26,10 +24,13 @@ Add IoC to rails with minimal fuss and ceremony.
|
|
26
24
|
- [Singletons](#singletons)
|
27
25
|
- [Nests](#nests)
|
28
26
|
- [Rails](#rails)
|
27
|
+
- [ActionController](#actioncontroller)
|
28
|
+
- [ActiveJob](#activejob)
|
29
|
+
- [ActiveRecord](#activerecord)
|
29
30
|
- [Contributing](#contributing)
|
30
31
|
- [License](#license)
|
31
32
|
|
32
|
-
<!--
|
33
|
+
<!-- /MarkdownTOC -->
|
33
34
|
|
34
35
|
## Dependency Injection
|
35
36
|
|
@@ -145,7 +146,7 @@ and setting the weapon. When a Hunter is created it's dependencies are also
|
|
145
146
|
created - and any of their dependencies and so on. Usage is equally simple
|
146
147
|
|
147
148
|
```ruby
|
148
|
-
hunter = scorpion.
|
149
|
+
hunter = scorpion.fetch Hunter
|
149
150
|
hunter.weapon # => a Weapon
|
150
151
|
```
|
151
152
|
|
@@ -158,7 +159,7 @@ scorpion.prepare do
|
|
158
159
|
hunt_for Axe
|
159
160
|
end
|
160
161
|
|
161
|
-
hunter = scorpion.
|
162
|
+
hunter = scorpion.fetch Hunter
|
162
163
|
hunter.weapon # => an Axe
|
163
164
|
```
|
164
165
|
|
@@ -173,7 +174,7 @@ Overriding hunters!
|
|
173
174
|
hunt_for Axe
|
174
175
|
end
|
175
176
|
|
176
|
-
hunter = scorpion.
|
177
|
+
hunter = scorpion.fetch Hunter
|
177
178
|
hunter # => Predator
|
178
179
|
hunter.weapon # => an Axe
|
179
180
|
```
|
@@ -185,49 +186,49 @@ Out of the box Scorpion does not need any configuration and will work
|
|
185
186
|
immediately. You can hunt for any Class even if it hasn't been configured.
|
186
187
|
|
187
188
|
```ruby
|
188
|
-
hash = Scorpion.instance.
|
189
|
+
hash = Scorpion.instance.fetch Hash
|
189
190
|
hash # => {}
|
190
191
|
```
|
191
192
|
|
192
|
-
###
|
193
|
+
### Objects
|
193
194
|
|
194
|
-
Scorpions feed their [Scorpion
|
195
|
+
Scorpions feed their [Scorpion Objects](lib/scorpion/object.rb) - any object that
|
195
196
|
should be fed its dependencies when it is created. Simply include the
|
196
|
-
Scorpion::
|
197
|
+
Scorpion::Object module into your class to benefit from Scorpion injections.
|
197
198
|
|
198
199
|
```ruby
|
199
200
|
class Keeper
|
200
|
-
include Scorpion::
|
201
|
+
include Scorpion::Object
|
201
202
|
|
202
|
-
|
203
|
+
depend_on do
|
203
204
|
lunch FastFood
|
204
205
|
end
|
205
206
|
end
|
206
207
|
|
207
208
|
class Zoo
|
208
|
-
include Scorpion::
|
209
|
+
include Scorpion::Object
|
209
210
|
|
210
|
-
|
211
|
+
depend_on do # or #depend_on if you like
|
211
212
|
keeper Zoo::Keeper
|
212
213
|
vet Zoo::Vet, lazy: true
|
213
214
|
end
|
214
215
|
end
|
215
216
|
|
216
|
-
zoo = scorpion.
|
217
|
+
zoo = scorpion.fetch Zoo
|
217
218
|
zoo.keeper # => an instance of a Zoo::Keeper
|
218
219
|
zoo.vet? # => false it hasn't been hunted down yet
|
219
220
|
zoo.vet # => an instnace of a Zoo::Vet
|
220
221
|
zoo.keeper.lunch # => an instance of FastFood
|
221
222
|
```
|
222
223
|
|
223
|
-
All of your classes should be
|
224
|
+
All of your classes should be objects! And any dependency that is also a Object will
|
224
225
|
be fed.
|
225
226
|
|
226
227
|
### Configuration
|
227
228
|
|
228
229
|
A good scorpion should be prepared to hunt. An effort that describes what the
|
229
230
|
scorpion hunts for and how it should be found. Scorpion uses Classes and Modules
|
230
|
-
as the primary means of identifying
|
231
|
+
as the primary means of identifying dependency in favor of opaque labels or strings.
|
231
232
|
This serves two benefits:
|
232
233
|
|
233
234
|
1. The type of object expected by the dependency is clearly identified making it
|
@@ -242,13 +243,13 @@ derived class). In the absence of any configuration, Scorpion will simply create
|
|
242
243
|
an instance of the specific class requested.
|
243
244
|
|
244
245
|
```ruby
|
245
|
-
scorpion.
|
246
|
+
scorpion.fetch Hash # => Hash.new
|
246
247
|
|
247
248
|
scorpion.prepare do
|
248
249
|
hunt_for Object::HashWithIndifferentAccess
|
249
250
|
end
|
250
251
|
|
251
|
-
scorpion.
|
252
|
+
scorpion.fetch Hash # => Object::HashWithIndifferentAccess.new
|
252
253
|
```
|
253
254
|
|
254
255
|
#### Modules
|
@@ -269,21 +270,21 @@ class Sword
|
|
269
270
|
include Sharp
|
270
271
|
end
|
271
272
|
|
272
|
-
poker = scorpion.
|
273
|
+
poker = scorpion.fetch Sharp
|
273
274
|
poker.poke # => "Module"
|
274
275
|
|
275
276
|
scorpion.prepare do
|
276
277
|
hunt_for Sword
|
277
278
|
end
|
278
279
|
|
279
|
-
poker = scorpion.
|
280
|
+
poker = scorpion.fetch Sharp
|
280
281
|
poker.poke # => "Sword"
|
281
282
|
```
|
282
283
|
|
283
284
|
#### Traits
|
284
285
|
|
285
|
-
Traits can be used to distinguish between
|
286
|
-
a scorpion may be prepare to hunt for several weapons and the
|
286
|
+
Traits can be used to distinguish between dependency of the same type. For example
|
287
|
+
a scorpion may be prepare to hunt for several weapons and the object needs a
|
287
288
|
blunt weapon.
|
288
289
|
|
289
290
|
```ruby
|
@@ -298,13 +299,13 @@ scorpion.prepare do
|
|
298
299
|
hunt_for Mace, :blunt, :sharp
|
299
300
|
end
|
300
301
|
|
301
|
-
scorpion.
|
302
|
-
scorpion.
|
303
|
-
scorpion.
|
302
|
+
scorpion.fetch Weapon, :blunt # => Hammer.new
|
303
|
+
scorpion.fetch Weapon, :sharp # => Sword.new
|
304
|
+
scorpion.fetch Weapon, :sharp, :blunt # => Mace.new
|
304
305
|
```
|
305
306
|
|
306
307
|
Modules can also be used to identify specific traits desired from the hunted
|
307
|
-
|
308
|
+
dependency.
|
308
309
|
|
309
310
|
```ruby
|
310
311
|
module Color; end
|
@@ -322,14 +323,14 @@ scorpion.prepare do
|
|
322
323
|
hunt_for SysLog
|
323
324
|
end
|
324
325
|
|
325
|
-
scorpion.
|
326
|
-
scorpion.
|
326
|
+
scorpion.fetch Logger, Color # => Console.new
|
327
|
+
scorpion.fetch Logger, Streaming # => SysLog.new
|
327
328
|
```
|
328
329
|
|
329
330
|
#### Builders
|
330
331
|
|
331
332
|
Sometimes resolving the correct dependencies is a bit more dynamic. In those
|
332
|
-
cases you can use a builder block to hunt for
|
333
|
+
cases you can use a builder block to hunt for dependency.
|
333
334
|
|
334
335
|
```ruby
|
335
336
|
class Samurai < Sword; end
|
@@ -342,11 +343,36 @@ scorpion.prepare do
|
|
342
343
|
end
|
343
344
|
```
|
344
345
|
|
346
|
+
Objects may also define their own .create methods that receive a scorpion and
|
347
|
+
arguments.
|
348
|
+
|
349
|
+
```ruby
|
350
|
+
class City
|
351
|
+
def self.create( scorpion, name )
|
352
|
+
klass = if name == "New York"
|
353
|
+
BigCity
|
354
|
+
else
|
355
|
+
SmallCity
|
356
|
+
end
|
357
|
+
|
358
|
+
klass.new name
|
359
|
+
end
|
360
|
+
|
361
|
+
def initialize( name )
|
362
|
+
@name = name
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
366
|
+
class BigCity < City; end
|
367
|
+
class SmallCity < City; end
|
368
|
+
|
369
|
+
```
|
370
|
+
|
345
371
|
#### Hunting Delegates
|
346
372
|
|
347
373
|
For really complex dependencies you may want to delegate the effort to retrieve
|
348
374
|
the dependencies to another type - a factory module for example. Scorpion
|
349
|
-
allows you to delegate hunting
|
375
|
+
allows you to delegate hunting dependency using the `:with` option.
|
350
376
|
|
351
377
|
```ruby
|
352
378
|
module ChocolateFactory
|
@@ -365,7 +391,7 @@ scorpion.prepare do
|
|
365
391
|
hunt_for Candy, with: ChocolateFactory
|
366
392
|
end
|
367
393
|
|
368
|
-
scorpion.
|
394
|
+
scorpion.fetch Candy, Nuget.new #=> Snickers.new Nugget.new
|
369
395
|
```
|
370
396
|
|
371
397
|
Any object that responds to `#call( scorpion, *args, &block )` can be used as
|
@@ -373,11 +399,11 @@ a hunting delegate.
|
|
373
399
|
|
374
400
|
#### Singletons
|
375
401
|
|
376
|
-
Scorpion allows you to capture
|
402
|
+
Scorpion allows you to capture dependency and feed the same instance to everyone that
|
377
403
|
asks for a matching dependency.
|
378
404
|
|
379
405
|
DI singletons are different then global singletons in that each scorpion can
|
380
|
-
have a unique instance of the class that it shares with all of it's
|
406
|
+
have a unique instance of the class that it shares with all of it's objects. This
|
381
407
|
allows, for example, global variable like support per-request without polluting
|
382
408
|
the global namespace or dealing with thread concurrency issues.
|
383
409
|
|
@@ -389,12 +415,12 @@ scorpion.prepare do
|
|
389
415
|
capture Logger
|
390
416
|
end
|
391
417
|
|
392
|
-
scorpion.
|
393
|
-
scorpion.
|
418
|
+
scorpion.fetch Logger # => Logger.new
|
419
|
+
scorpion.fetch Logger # => Previously captured logger
|
394
420
|
```
|
395
421
|
|
396
422
|
Captured dependencies are not shared with child scorpions (for example when
|
397
|
-
conceiving scorpions from a [Nest](Nests)). To share captured
|
423
|
+
conceiving scorpions from a [Nest](Nests)). To share captured dependency with children
|
398
424
|
use `share`.
|
399
425
|
|
400
426
|
### Nests
|
@@ -412,11 +438,13 @@ nest.prepare do
|
|
412
438
|
end
|
413
439
|
|
414
440
|
scorpion = nest.conceive
|
415
|
-
scorpion.
|
441
|
+
scorpion.fetch Logger # => Logger.new
|
416
442
|
```
|
417
443
|
|
418
444
|
### Rails
|
419
445
|
|
446
|
+
#### ActionController
|
447
|
+
|
420
448
|
Scorpion provides simple integration into for rails controllers to establish
|
421
449
|
a scorpion for each request.
|
422
450
|
|
@@ -441,12 +469,9 @@ end
|
|
441
469
|
require 'scorpion'
|
442
470
|
|
443
471
|
class ApplicationController < ActionController::Base
|
444
|
-
|
445
|
-
|
446
|
-
feed_on do
|
472
|
+
depend_on do
|
447
473
|
users UserService, lazy: true
|
448
474
|
end
|
449
|
-
|
450
475
|
end
|
451
476
|
|
452
477
|
# users_controller.rb
|
@@ -458,6 +483,48 @@ class UsersController < ApplicationController
|
|
458
483
|
end
|
459
484
|
```
|
460
485
|
|
486
|
+
#### ActiveJob
|
487
|
+
|
488
|
+
Simliar to support for controllers, Scorpion provides support for dependency
|
489
|
+
injection into ActiveJob objects.
|
490
|
+
|
491
|
+
```ruby
|
492
|
+
|
493
|
+
# avatar_job.rb
|
494
|
+
class AvatarJob < ActiveJob::Base
|
495
|
+
def perform( id )
|
496
|
+
user = users.find( id )
|
497
|
+
logger.write "Found a user: #{ user }"
|
498
|
+
end
|
499
|
+
end
|
500
|
+
```
|
501
|
+
|
502
|
+
#### ActiveRecord
|
503
|
+
|
504
|
+
Scorpion enhances ActiveRecord models to support resolving dependencies from
|
505
|
+
a scorpion and sharing that scorpion with all associations.
|
506
|
+
|
507
|
+
```ruby
|
508
|
+
class User < ActiveRecord::Base
|
509
|
+
depend_on do
|
510
|
+
credentials Service::Auth::Credentials
|
511
|
+
end
|
512
|
+
|
513
|
+
def check_password( password )
|
514
|
+
credentials.check encoded_password, password
|
515
|
+
end
|
516
|
+
end
|
517
|
+
|
518
|
+
class SessionsController < ActionController::Base
|
519
|
+
|
520
|
+
def create
|
521
|
+
user = User.with_scorpion( scorpion ).find params[:id]
|
522
|
+
sign_in if user.check_password( params[:password] )
|
523
|
+
end
|
524
|
+
end
|
525
|
+
```
|
526
|
+
|
527
|
+
|
461
528
|
## Contributing
|
462
529
|
|
463
530
|
1. Fork it ( https://github.com/phallguy/scorpion/fork )
|
data/lib/scorpion/attribute.rb
CHANGED
@@ -35,7 +35,7 @@ module Scorpion
|
|
35
35
|
attributes.key? name
|
36
36
|
end
|
37
37
|
|
38
|
-
# Defines the food that {Scorpion::
|
38
|
+
# Defines the food that {Scorpion::Object} will feed on. A food is defined by
|
39
39
|
# invoking a method with the desired name passing the contract and traits
|
40
40
|
# desired. AttributeSet uses method_missing to dynamically define
|
41
41
|
# attributes.
|
@@ -70,18 +70,26 @@ module Scorpion
|
|
70
70
|
@defining_attributes = false
|
71
71
|
end
|
72
72
|
|
73
|
+
# Define a single attribute with the given name that expects food that will
|
74
|
+
# satisfy the contract and traits.
|
75
|
+
# @param [String] name of the attribute.
|
76
|
+
# @param [Class,Module,Symbol] contract that describes the desired behavior
|
77
|
+
# of the injected object.
|
78
|
+
# @param [Array<Symbol>] traits that must match on instances of the {#contract}
|
79
|
+
# @return [Attribute] the attribute that was created.
|
80
|
+
def define_attribute( name, contract, *traits )
|
81
|
+
options = traits.pop if traits.last.is_a? Hash
|
82
|
+
options ||= {}
|
83
|
+
attributes[name.to_sym] = Attribute.new name, contract, traits, options
|
84
|
+
end
|
85
|
+
|
86
|
+
|
73
87
|
protected
|
74
88
|
|
75
89
|
attr_reader :attributes
|
76
90
|
|
77
91
|
private
|
78
92
|
|
79
|
-
def define_attribute( name, contract, *traits )
|
80
|
-
options = traits.pop if traits.last.is_a? Hash
|
81
|
-
options ||= {}
|
82
|
-
attributes[name.to_sym] = Attribute.new name, contract, traits, options
|
83
|
-
end
|
84
|
-
|
85
93
|
def method_missing( name, *args )
|
86
94
|
return super unless @defining_attributes
|
87
95
|
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'scorpion/dependency'
|
2
|
+
|
3
|
+
module Scorpion
|
4
|
+
class Dependency
|
5
|
+
# {Dependency} for an captured argument.
|
6
|
+
# @see {Scorpion#argument}.
|
7
|
+
class ArgumentDependency < Scorpion::Dependency
|
8
|
+
|
9
|
+
attr_reader :argument
|
10
|
+
|
11
|
+
def initialize( argument )
|
12
|
+
@argument = argument
|
13
|
+
end
|
14
|
+
|
15
|
+
def fetch( *args )
|
16
|
+
argument
|
17
|
+
end
|
18
|
+
|
19
|
+
def satisfies?( contract, traits = nil )
|
20
|
+
contract === argument && traits.blank?
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -1,17 +1,17 @@
|
|
1
|
-
require 'scorpion/
|
1
|
+
require 'scorpion/dependency'
|
2
2
|
|
3
3
|
module Scorpion
|
4
|
-
class
|
5
|
-
# {
|
4
|
+
class Dependency
|
5
|
+
# {Dependency} that delegates to another object that implements
|
6
6
|
# #call( scorpion, *args, &block ).
|
7
|
-
class
|
7
|
+
class BuilderDependency < Scorpion::Dependency
|
8
8
|
|
9
9
|
# ============================================================================
|
10
10
|
# @!group Attributes
|
11
11
|
#
|
12
12
|
|
13
13
|
# @!attribute
|
14
|
-
# @return [#call(scorpion,*args,&block)] the builder to use to fetch instances of the
|
14
|
+
# @return [#call(scorpion,*args,&block)] the builder to use to fetch instances of the dependency.
|
15
15
|
attr_reader :builder
|
16
16
|
|
17
17
|
#
|
@@ -22,9 +22,9 @@ module Scorpion
|
|
22
22
|
super contract, traits
|
23
23
|
end
|
24
24
|
|
25
|
-
# @see Scorpion::
|
26
|
-
def fetch(
|
27
|
-
builder.call(
|
25
|
+
# @see Scorpion::Dependency#fetch
|
26
|
+
def fetch( hunt )
|
27
|
+
builder.call( hunt, *hunt.arguments, &hunt.block )
|
28
28
|
end
|
29
29
|
|
30
30
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'scorpion/dependency'
|
2
|
+
|
3
|
+
module Scorpion
|
4
|
+
class Dependency
|
5
|
+
class CapturedDependency < Scorpion::Dependency
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
# ============================================================================
|
9
|
+
# @!group Attributes
|
10
|
+
#
|
11
|
+
|
12
|
+
# @!attribute
|
13
|
+
# @return [Object] the instance that was captured.
|
14
|
+
attr_reader :instance
|
15
|
+
|
16
|
+
# @!attribute
|
17
|
+
# @return [Scorpion::Dependency] the actual dependency to hunt. Used to fetch the
|
18
|
+
# single {#instance}.
|
19
|
+
attr_reader :specific_dependency
|
20
|
+
private :specific_dependency
|
21
|
+
|
22
|
+
|
23
|
+
delegate [:contract,:traits,:satisfies?] => :specific_dependency
|
24
|
+
|
25
|
+
#
|
26
|
+
# @!endgroup Attributes
|
27
|
+
|
28
|
+
def initialize( specific_dependency )
|
29
|
+
@specific_dependency = specific_dependency
|
30
|
+
end
|
31
|
+
|
32
|
+
# @see Dependency#fetch
|
33
|
+
def fetch( hunt )
|
34
|
+
@instance ||= specific_dependency.fetch( hunt )
|
35
|
+
end
|
36
|
+
|
37
|
+
# @see Dependency#release
|
38
|
+
def release
|
39
|
+
@instance = nil
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'scorpion/dependency'
|
2
|
+
|
3
|
+
module Scorpion
|
4
|
+
class Dependency
|
5
|
+
# {Dependency} for a {Class} contract
|
6
|
+
class ClassDependency < Scorpion::Dependency
|
7
|
+
|
8
|
+
def fetch( hunt )
|
9
|
+
hunt.scorpion.spawn hunt, hunt.contract, *resolve_arguments( hunt ), &hunt.block
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def resolve_arguments( hunt )
|
15
|
+
arguments = hunt.arguments
|
16
|
+
return arguments unless arguments.blank? && hunt.contract < Scorpion::Object
|
17
|
+
|
18
|
+
hunt.contract.initializer_injections.each_with_object([]) do |attr,args|
|
19
|
+
args << hunt.fetch_by_traits( attr.contract, attr.traits )
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|