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
Public Class Methods
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
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
initial implementation for a clean Container
# File lib/dim.rb, line 103 def self.service_list [] end
Public Instance Methods
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
Resets the cached services
# File lib/dim.rb, line 122 def clear_cache! @cache = {} end
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 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
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
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
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
# File lib/dim.rb, line 57 def to_s info = " services: #{service_list}" "<Dim::Container::#{self.__id__}:#{info}>" end