Module: MinDI::Injectable

Included in:
InjectableContainer
Defined in:
lib/mindi.rb

Overview

Include this in a container class to allow use of #inject_into within services. See examples/inject.rb. Including this module also extends the class with the Container module, so a simple shortcut to making a fully functional injectable container is to simply include Injectable.

This module can be used outside of the context of MinDI::Container: almost any object can be injected into any other. For example:

x = [1,2,3]
y = {}
x.extend MinDI::Injectable
x.inject_into y
p y.reverse      => [3, 2, 1]

Note that injecting an Injectable object into another object never interferes with methods of the latter object.

Note that injected methods operate on the injecting instance, not the injectee. So instance variables…

Note similarity to Forwardable and Delegator in the stdlib. However, Injectable is more passive in that (as noted above) it only affects the handling of methods that are missing in the target object. In that respect, Injectable is a little like inheritance (except as noted above about which instance is operated on).

Defined Under Namespace

Modules: Injected Classes: NoInjectedMethodError, NonUniqueContainerError

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(m, *rest) ⇒ Object

:nodoc:



328
329
330
# File 'lib/mindi.rb', line 328

def method_missing(m, *rest) # :nodoc:
  raise NoInjectedMethodError
end

Instance Method Details

#inject_into(obj) ⇒ Object

Inject the container’s services into obj. The service methods can be called from within the object’s methods, and they will return the same objects as if they were called from the container.

Returns obj, so that the method can be called within service definitions.



309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
# File 'lib/mindi.rb', line 309

def inject_into obj
  begin
    obj.extend Injected
  rescue TypeError
    warn "#{caller[2]}: warning: class #{obj.class} cannot be injected into"
    return obj
  end

  cont = obj.instance_variable_get(:@__injectable__object__)
  if cont and cont != self
    raise NonUniqueContainerError,
      "Object #{obj.inspect} already belongs to #{cont.inspect}." +
      " Was attempting to inject #{self.inspect} into it."
  end
  
  obj.instance_variable_set(:@__injectable__object__, self)
  obj
end