Class: DiFtw::Injector

Inherits:
Object
  • Object
show all
Defined in:
lib/diftw/injector.rb

Overview

The Injector class. Create an instance to start registering and injecting dependencies.

DI = DiFtw::Injector.new

# You can call register on the Injector object
DI.singleton :bar do
  Bar.new
end

Alternatively, you can pass a block to the initializer and register your depencies right inside it:

DI = DiFtw::Injector.new do
  singleton :foo do
    Foo.new
  end
end

Instance Method Summary collapse

Constructor Details

#initialize(parent: nil, &registrator) ⇒ Injector

Instantiate a new Injector.

DI = DiFtw::Injector.new


37
38
39
40
# File 'lib/diftw/injector.rb', line 37

def initialize(parent: nil, &registrator)
  @registry, @parent = {}, parent
  instance_eval(&registrator) if registrator
end

Instance Method Details

#delete(name) ⇒ DiFtw::Injector

Unregisters the dependency from this injector instance. This means requests for this dependency will continue on up the chain.

Parameters:

  • name (Symbol)

    name of the dependency

Returns:



105
106
107
108
# File 'lib/diftw/injector.rb', line 105

def delete(name)
  registry.delete name
  self
end

#factory(name, deps = [], &y) ⇒ DiFtw::Injector

Register a new dependency by passing a Proc or a block. Each time you inject it, the block/Proc will be re-run and you’ll get the result.

DI.factory :foo do
  Foo
end

Parameters:

  • name (Symbol)

    name of the dependency

  • deps (Array<Symbol>) (defaults to: [])

    Array of dependencies to inject into the provider block

  • y (Proc)

    the dependency wrapped in a Proc or block

Returns:



75
76
77
78
79
# File 'lib/diftw/injector.rb', line 75

def factory(name, deps = [], &y)
  provider = Provider.new(self, name, y, deps)
  registry[name] = Factory.new(provider)
  self
end

#fetch(name) ⇒ Object Also known as: []

Fetches a dependency by name (calls the Proc/block).

Returns:

  • whatever the Proc/block returns



86
87
88
89
90
91
92
93
94
# File 'lib/diftw/injector.rb', line 86

def fetch(name)
  if parent.nil?
    registry.fetch(name).resolve
  elsif registry.has_key? name
    registry[name].resolve
  else
    parent[name]
  end
end

#inject(*dependencies) ⇒ Object

Creates and returns a new Module which contains instance methods for all the dependencies you specified. Simply include this module in your class, and all it’s instances will have their dependencies injected. Or extend your class with this module, and your class itself will have the dependencies injected.

class Widget
  include DI.inject :foo, :bar
end
Widget.new.foo

class Spline
  extend Di.inject :foo
end
Spline.foo

Parameters:

  • dependencies (Symbol)

    All dependency names you want to inject.



127
128
129
# File 'lib/diftw/injector.rb', line 127

def inject(*dependencies)
  DiFtw::Builder.injector_module self, dependencies
end

#inject_instance(instance, *dependencies) ⇒ Object

Injects dependencies into a specific, existing object.

DI.inject_instance obj, :foo, :bar

Parameters:

  • instance (Object)

    The object you wish to inject dependencies into

  • dependencies (Symbol)

    All dependency names you want to inject.



139
140
141
142
# File 'lib/diftw/injector.rb', line 139

def inject_instance(instance, *dependencies)
     mod = DiFtw::Builder.injector_module self, dependencies
     instance.singleton_class.send :include, mod
end

#singleton(name, deps = [], &y) ⇒ DiFtw::Injector

Register a new dependency as a singleton. The proc will only be called the first time, then the returned value will be stored and returned for subsequent injections. Threadsafe.

DI.singleton :foo do
  Foo
end

Parameters:

  • name (Symbol)

    name of the dependency

  • deps (Array<Symbol>) (defaults to: [])

    Array of dependencies to inject into the provider block

  • y (Proc)

    the dependency wrapped in a Proc or block

Returns:



56
57
58
59
60
# File 'lib/diftw/injector.rb', line 56

def singleton(name, deps = [], &y)
  provider = Provider.new(self, name, y, deps)
  registry[name] = Singleton.new(provider)
  self
end