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
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
|