Module Dissident
In: lib/nukumi2/vendor/dissident.rb

Dissident — a Ruby dependency injection container

Copyright (C) 2005 Christian Neukirchen <chneukirchen@gmail.com>

This work is licensed under the same terms as Ruby itself.

Methods

Classes and Modules

Class Dissident::Cache
Class Dissident::Container
Class Dissident::MissingServiceError
Class Dissident::Prototype

Constants

VERSION = "0.2"
INJECTED = {}   A hash containing classes to inject in as keys.
LIBRARIES = {}   A hash mapping classes to the libraries they belong to.

Public Class methods

Return the declared dependencies of klass that are to be injected using Constructor Injection.

[Source]

     # File lib/nukumi2/vendor/dissident.rb, line 160
160:     def constructor_parameters(klass)
161:       if klass.const_defined? :DISSIDENT_CONSTRUCTOR
162:         container = container_for klass
163:         klass.const_get(:DISSIDENT_CONSTRUCTOR).map { |service|
164:           container.fetch service
165:         }
166:       else
167:         # By default, inject no constructor parameters.
168:         []
169:       end
170:     end

Set the global default container to default. Usually not needed, it is better style to use Dissident.with.

[Source]

    # File lib/nukumi2/vendor/dissident.rb, line 82
82:     def container=(default)
83:       Thread.main[:DISSIDENT_CONTAINER][nil] = if default.nil?
84:                                                  nil
85:                                                else
86:                                                  Dissident.instantiate default
87:                                                end
88:     end

Return the container that will be used for injecting dependencies into objects of klass.

[Source]

     # File lib/nukumi2/vendor/dissident.rb, line 174
174:     def container_for(klass)
175:       copy_binding
176:       Thread.current[:DISSIDENT_CONTAINER].fetch(library(klass))
177:     end

Inject all the dependencies of object.

[Source]

     # File lib/nukumi2/vendor/dissident.rb, line 143
143:     def inject(object)
144:       if object.class.ancestors.any? { |a| INJECTED[a] }
145:         container = container_for object.class
146:         
147:         if container.nil?
148:           warn "Dissident: Cannot inject to #{object} " <<
149:             "(#{library(object.class) || "default application"}), " <<
150:             "no container given."
151:         else
152:           object.instance_variable_set :@__dissident__, container
153:         end
154:       end
155:       object
156:     end

Instantiate object (a Dissident::Container) to be used for dependency injection.

[Source]

     # File lib/nukumi2/vendor/dissident.rb, line 92
 92:     def instantiate(object)
 93:       if object.kind_of? Class and object < Container
 94:         cont = object.new
 95:         cache = Cache.new(cont)
 96:         cont.cache = cache
 97:       else
 98:         raise ArgumentError, "#{object} is not a Dissident::Container"
 99:       end
100:     end

Register klass to make use of Dissident.

This needs only to be explicitly called when you declare Constructor Injection with DISSIDENT_CONSTRUCTOR.

It is recommended to make use of provide instead of this.

[Source]

     # File lib/nukumi2/vendor/dissident.rb, line 138
138:     def use_for(klass)
139:       klass.use_dissident!
140:     end

Make cont the current global container in block.

Optionally, pass a hash that maps libraries to the container used for them. Example:

  Dissident.with MyGlobalContainer,
                 MyFirstLib => FirstContainer,
                 MySecondLib => SecondContainer do
    ...
  end

[Source]

     # File lib/nukumi2/vendor/dissident.rb, line 112
112:     def with(cont, library = nil, &block)
113:       if cont.kind_of? Hash or library.kind_of? Hash
114:         if library.nil?
115:           recurse cont, &block
116:         else
117:           with(cont) { recurse library, &block }
118:         end
119:       else
120:         if block.nil?
121:           raise ArgumentError, "Dissident.with must be called with a block"
122:         end
123: 
124:         cont = instantiate cont
125:         
126:         fluid_let(library, cont) {
127:           yield cont
128:         }
129:       end
130:     end

Private Class methods

[Source]

     # File lib/nukumi2/vendor/dissident.rb, line 216
216:     def copy_binding
217:       unless Thread.current.key? :DISSIDENT_CONTAINER
218:         Thread.current[:DISSIDENT_CONTAINER] =
219:           Thread.main[:DISSIDENT_CONTAINER].dup
220:       end
221:     end

[Source]

     # File lib/nukumi2/vendor/dissident.rb, line 203
203:     def fluid_let(library, value, &block)
204:       copy_binding
205: 
206:       old_value = Thread.current[:DISSIDENT_CONTAINER][library]
207:       Thread.current[:DISSIDENT_CONTAINER][library] = value
208:       
209:       begin
210:         block.call
211:       ensure
212:         Thread.current[:DISSIDENT_CONTAINER][library] = old_value
213:       end
214:     end

[Source]

     # File lib/nukumi2/vendor/dissident.rb, line 181
181:     def library(klass)
182:       LIBRARIES.fetch(klass) {
183:         if klass.superclass
184:           library klass.superclass
185:         end
186:       }
187:     end

[Source]

     # File lib/nukumi2/vendor/dissident.rb, line 189
189:     def recurse(rest, &block)
190:       library = rest.keys.first
191:       cont = rest.delete library
192:       
193:       # Zip down recursively.
194:       if rest.empty?
195:         with(cont, library, &block)
196:       else
197:         with(cont, library) {
198:           with rest, &block
199:         }
200:       end
201:     end

[Validate]