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.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/.rspec +2 -1
  4. data/README.md +111 -44
  5. data/lib/scorpion/attribute.rb +0 -1
  6. data/lib/scorpion/attribute_set.rb +15 -7
  7. data/lib/scorpion/dependency/argument_dependency.rb +25 -0
  8. data/lib/scorpion/{prey/builder_prey.rb → dependency/builder_dependency.rb} +8 -8
  9. data/lib/scorpion/dependency/captured_dependency.rb +44 -0
  10. data/lib/scorpion/dependency/class_dependency.rb +25 -0
  11. data/lib/scorpion/dependency/module_dependency.rb +14 -0
  12. data/lib/scorpion/dependency.rb +137 -0
  13. data/lib/scorpion/dependency_map.rb +135 -0
  14. data/lib/scorpion/hunt.rb +158 -0
  15. data/lib/scorpion/hunter.rb +21 -20
  16. data/lib/scorpion/locale/en.yml +5 -1
  17. data/lib/scorpion/{king.rb → object.rb} +72 -53
  18. data/lib/scorpion/object_constructor.rb +55 -0
  19. data/lib/scorpion/rails/active_record/association.rb +65 -0
  20. data/lib/scorpion/rails/active_record/model.rb +28 -0
  21. data/lib/scorpion/rails/active_record/relation.rb +66 -0
  22. data/lib/scorpion/rails/active_record.rb +21 -0
  23. data/lib/scorpion/rails/controller.rb +22 -62
  24. data/lib/scorpion/rails/job.rb +30 -0
  25. data/lib/scorpion/rails/nest.rb +86 -0
  26. data/lib/scorpion/rails/railtie.rb +16 -0
  27. data/lib/scorpion/rails.rb +4 -0
  28. data/lib/scorpion/rspec/helper.rb +25 -0
  29. data/lib/scorpion/rspec.rb +17 -0
  30. data/lib/scorpion/stinger.rb +69 -0
  31. data/lib/scorpion/version.rb +1 -1
  32. data/lib/scorpion.rb +91 -44
  33. data/scorpion.gemspec +1 -1
  34. data/spec/internal/app/models/author.rb +17 -0
  35. data/spec/internal/app/models/todo.rb +14 -0
  36. data/spec/internal/db/schema.rb +12 -1
  37. data/spec/lib/scorpion/dependency/argument_dependency_spec.rb +18 -0
  38. data/spec/lib/scorpion/dependency/builder_dependency_spec.rb +41 -0
  39. data/spec/lib/scorpion/dependency/module_dependency_spec.rb +16 -0
  40. data/spec/lib/scorpion/dependency_map_spec.rb +108 -0
  41. data/spec/lib/scorpion/dependency_spec.rb +131 -0
  42. data/spec/lib/scorpion/hunt_spec.rb +93 -0
  43. data/spec/lib/scorpion/hunter_spec.rb +53 -14
  44. data/spec/lib/scorpion/object_constructor_spec.rb +49 -0
  45. data/spec/lib/scorpion/object_spec.rb +214 -0
  46. data/spec/lib/scorpion/rails/active_record/association_spec.rb +26 -0
  47. data/spec/lib/scorpion/rails/active_record/model_spec.rb +33 -0
  48. data/spec/lib/scorpion/rails/active_record/relation_spec.rb +72 -0
  49. data/spec/lib/scorpion/rails/controller_spec.rb +9 -9
  50. data/spec/lib/scorpion/rails/job_spec.rb +34 -0
  51. data/spec/lib/scorpion/rspec/helper_spec.rb +44 -0
  52. data/spec/lib/scorpion_spec.rb +0 -35
  53. data/spec/spec_helper.rb +1 -0
  54. metadata +54 -26
  55. data/lib/scorpion/hunting_map.rb +0 -139
  56. data/lib/scorpion/prey/captured_prey.rb +0 -44
  57. data/lib/scorpion/prey/class_prey.rb +0 -13
  58. data/lib/scorpion/prey/hunted_prey.rb +0 -14
  59. data/lib/scorpion/prey/module_prey.rb +0 -14
  60. data/lib/scorpion/prey.rb +0 -94
  61. data/spec/internal/db/combustion_test.sqlite +0 -0
  62. data/spec/lib/scorpion/hunting_map_spec.rb +0 -126
  63. data/spec/lib/scorpion/instance_spec.rb +0 -5
  64. data/spec/lib/scorpion/king_spec.rb +0 -198
  65. data/spec/lib/scorpion/prey/builder_prey_spec.rb +0 -42
  66. data/spec/lib/scorpion/prey/module_prey_spec.rb +0 -16
  67. data/spec/lib/scorpion/prey_spec.rb +0 -76
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5ec2ff4bcf7bacc05263624d567a42ffa57d614c
4
- data.tar.gz: 1f52f7c0031504a0b0e926ff507d49af659fa717
3
+ metadata.gz: d9f9e729630d83f9132e46118f0a74a9bcc9946f
4
+ data.tar.gz: 40a34e024069aaf348ce03b37065d83098920e40
5
5
  SHA512:
6
- metadata.gz: 6b6e3b77742c496ff2b3ceee4484bcd8e8eb69d63029e1d232453c34775135c1c0088a144df31528724866c2e84209cd17f2bcb3cf47cbf90b2840315aa99c12
7
- data.tar.gz: b55c22cd4c397caf6c9ea10bfde2f892dc083f6eae906c54b7b724103f6b88fb627ee2ff8638667df68f538fbb503b4bd7a5a1a5048062c77ebab0e978e7475b
6
+ metadata.gz: 32a04845861b9ea89cd5dcd19c667a0a339a424513c7b610f9909c3995e37d45707f837f3b10c8ce2d844ef12698268ffaa50c2afde083f54cd3161c4877d792
7
+ data.tar.gz: 435e3fbc679d5ad65fc7f5d2cce00adb802b5c73b91d1995f15c9012f6b0a8a99cee97c70cf7907b391d71fe831b8f8b38958249ef89ced063a9b0654a5f2f2e
data/.gitignore CHANGED
@@ -20,4 +20,5 @@ tmp
20
20
  *.o
21
21
  *.a
22
22
  mkmf.log
23
- .env
23
+ .env
24
+ *.sqlite
data/.rspec CHANGED
@@ -1,2 +1,3 @@
1
1
  --color
2
- --format Fuubar
2
+ --format Fuubar
3
+
data/README.md CHANGED
@@ -8,15 +8,13 @@
8
8
 
9
9
  Add IoC to rails with minimal fuss and ceremony.
10
10
 
11
- <!-- START doctoc generated TOC please keep comment here to allow auto update -->
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
- - [Kings](#kings)
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
- <!-- END doctoc generated TOC please keep comment here to allow auto update -->
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.hunt Hunter
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.hunt Hunter
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.hunt Hunter
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.hunt Hash
189
+ hash = Scorpion.instance.fetch Hash
189
190
  hash # => {}
190
191
  ```
191
192
 
192
- ### Kings
193
+ ### Objects
193
194
 
194
- Scorpions feed their [Scorpion Kings](lib/scorpion/king.rb) - any object that
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::King module into your class to benefit from Scorpion injections.
197
+ Scorpion::Object module into your class to benefit from Scorpion injections.
197
198
 
198
199
  ```ruby
199
200
  class Keeper
200
- include Scorpion::King
201
+ include Scorpion::Object
201
202
 
202
- feed_on do
203
+ depend_on do
203
204
  lunch FastFood
204
205
  end
205
206
  end
206
207
 
207
208
  class Zoo
208
- include Scorpion::King
209
+ include Scorpion::Object
209
210
 
210
- feed_on do # or #depend_on if you like
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.hunt Zoo
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 kings! And any dependency that is also a King will
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 prey in favor of opaque labels or strings.
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.hunt Hash # => Hash.new
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.hunt Hash # => Object::HashWithIndifferentAccess.new
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.hunt Sharp
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.hunt Sharp
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 prey of the same type. For example
286
- a scorpion may be prepare to hunt for several weapons and the king needs a
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.hunt Weapon, :blunt # => Hammer.new
302
- scorpion.hunt Weapon, :sharp # => Sword.new
303
- scorpion.hunt Weapon, :sharp, :blunt # => Mace.new
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
- prey.
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.hunt Logger, Color # => Console.new
326
- scorpion.hunt Logger, Streaming # => SysLog.new
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 prey.
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 prey using the `:with` option.
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.hunt Candy, Nuget.new #=> Snickers.new Nugget.new
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 prey and feed the same instance to everyone that
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 kings. This
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.hunt Logger # => Logger.new
393
- scorpion.hunt Logger # => Previously captured logger
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 prey with children
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.hunt Logger # => Logger.new
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
- include Scorpion::Rails::Controller
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 )
@@ -32,7 +32,6 @@ module Scorpion
32
32
  # @return [Boolean] true if the attribute should have a public writer.
33
33
  def private?; @private end
34
34
 
35
-
36
35
  #
37
36
  # @!endgroup Attributes
38
37
 
@@ -35,7 +35,7 @@ module Scorpion
35
35
  attributes.key? name
36
36
  end
37
37
 
38
- # Defines the food that {Scorpion::King} will feed on. A food is defined by
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/prey'
1
+ require 'scorpion/dependency'
2
2
 
3
3
  module Scorpion
4
- class Prey
5
- # {Prey} that delegates to another object that implements
4
+ class Dependency
5
+ # {Dependency} that delegates to another object that implements
6
6
  # #call( scorpion, *args, &block ).
7
- class BuilderPrey < Scorpion::Prey
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 prey.
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::Prey#fetch
26
- def fetch( scorpion, *args, &block )
27
- builder.call( scorpion, *args, &block )
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
@@ -0,0 +1,14 @@
1
+ require 'scorpion/dependency'
2
+
3
+ module Scorpion
4
+ class Dependency
5
+ # {Dependency} for a {Module} contract
6
+ class ModuleDependency < Scorpion::Dependency
7
+
8
+ def fetch( *args )
9
+ contract
10
+ end
11
+
12
+ end
13
+ end
14
+ end