class Dim::Container

Dim::Container is the central data store for registering services used for dependency injuction. Users register services by providing a name and a block used to create the service. Services may be retrieved by asking for them by name (via the [] operator) or by selector (via the method_missing technique).

Attributes

parent[R]

Public Class Methods

new(parent=nil) click to toggle source

Create a dependency injection container. Specify a parent container to use as a fallback for service lookup.

# File lib/dim.rb, line 51
def initialize(parent=nil)
  @services = {}
  @cache = {}
  @parent = parent || Container
end
service_block(name) click to toggle source

Searching for a service block only reaches the Container class when all the containers in the hierarchy search chain have no entry for the service. In this case, the only thing to do is signal a failure.

# File lib/dim.rb, line 130
def self.service_block(name)
  fail(MissingServiceError, "Unknown Service '#{name}'")
end
service_list() click to toggle source

initial implementation for a clean Container

# File lib/dim.rb, line 103
def self.service_list
  []
end

Public Instance Methods

[](name) click to toggle source

Lookup a service by name. Throw an exception if no service is found.

# File lib/dim.rb, line 91
def [](name)
  @cache[name] ||= service_block(name).call(self)
end
clear_cache!() click to toggle source

Resets the cached services

# File lib/dim.rb, line 122
def clear_cache!
  @cache = {}
end
method_missing(sym, *args, &block) click to toggle source

Lookup a service by message selector. A service with the same name as sym will be returned, or an exception is thrown if no matching service is found.

# File lib/dim.rb, line 110
def method_missing(sym, *args, &block)
  self[sym]
end
register(name, &block) click to toggle source

Register a service named name. The block will be used to create the service on demand. It is recommended that symbols be used as the name of a service.

# File lib/dim.rb, line 65
def register(name, &block)
  if @services[name]
    fail DuplicateServiceError, "Duplicate Service Name '#{name}'"
  end
  @services[name] = block

  self.class.send(:define_method, name) do
    self[name]
  end
end
register_env(name) click to toggle source

Lookup a service from ENV variables; fall back to searching the container and its parents for a default value

# File lib/dim.rb, line 77
def register_env(name)
  if value = ENV[name.to_s.upcase]
    register(name) { value }
  else
    begin
      @parent.service_block(name)
    rescue MissingServiceError
      raise EnvironmentVariableNotFound, "Could not find an ENV variable named #{name.to_s.upcase} nor could we find a service named #{name} in the parent container"
    end
  end
end
service_block(name) click to toggle source

Return the block that creates the named service. Throw an exception if no service creation block of the given name can be found in the container or its parents.

# File lib/dim.rb, line 117
def service_block(name)
  @services[name] || @parent.service_block(name)
end
service_list() click to toggle source

a list with services, that this container provides @return [Array]

# File lib/dim.rb, line 98
def service_list
  (@services.keys + @parent.service_list).flatten.uniq
end
to_s() click to toggle source
# File lib/dim.rb, line 57
def to_s
  info = " services: #{service_list}"
  "<Dim::Container::#{self.__id__}:#{info}>"
end