Class: Wireless::Registry
- Inherits:
-
Object
- Object
- Wireless::Registry
- Includes:
- Fetch
- Defined in:
- lib/wireless/registry.rb
Overview
The public API of the dependency provider (AKA service locator). A hash-like object which maps names (symbols) to dependencies (objects) via blocks which either resolve the dependency every time (factory) or once (singleton).
A class can be supplied instead of the block, in which case it is equivalent to a block which calls new
on the class, e.g.:
WL = Wireless.new do
on(:foo, Foo)
end
is equivalent to:
WL = Wireless.new do
on(:foo) { Foo.new }
end
Constant Summary collapse
- DEFAULT_EXPORTS =
{ private: [], protected: [], public: [] }
- DEFAULT_VISIBILITY =
:private
Instance Method Summary collapse
-
#factory(name, klass = nil, &block) ⇒ Object
(also: #on)
Registers a dependency which is resolved every time its value is fetched.
-
#include?(key) ⇒ Boolean
Returns true if a dependency with the specified name has been registered, false otherwise.
-
#initialize(default_visibility = DEFAULT_VISIBILITY, &block) ⇒ Registry
constructor
A new instance of Registry.
-
#mixin(args) ⇒ Object
Takes an array or hash specifying the dependencies to export, and returns a module which defines getters for those dependencies.
-
#singleton(name, klass = nil, &block) ⇒ Object
(also: #once)
Registers a dependency which is only resolved the first time its value is fetched.
Methods included from Fetch
Constructor Details
#initialize(default_visibility = DEFAULT_VISIBILITY, &block) ⇒ Registry
Returns a new instance of Registry.
29 30 31 32 33 34 35 |
# File 'lib/wireless/registry.rb', line 29 def initialize(default_visibility = DEFAULT_VISIBILITY, &block) @default_visibility = default_visibility @module_cache = SynchronizedStore.new(type: :module) @registry = SynchronizedStore.new(type: :resolver) @seen = Set.new instance_eval(&block) if block end |
Instance Method Details
#factory(name, klass = nil, &block) ⇒ Object Also known as: on
Registers a dependency which is resolved every time its value is fetched.
38 39 40 |
# File 'lib/wireless/registry.rb', line 38 def factory(name, klass = nil, &block) @registry[name.to_sym] = Resolver::Factory.new(block || klass) end |
#include?(key) ⇒ Boolean
Returns true if a dependency with the specified name has been registered, false otherwise
44 45 46 |
# File 'lib/wireless/registry.rb', line 44 def include?(key) @registry.include?(key) end |
#mixin(args) ⇒ Object
Takes an array or hash specifying the dependencies to export, and returns a module which defines getters for those dependencies.
class Test
# hash (specify visibilities)
include Services.mixin private: :foo, protected: i[ baz], public: :quux
# or an array of imports using the default visibility (:private by default)
include Services.mixin i[foo baz quux]
def test
foo + + baz + quux # access the dependencies
end
end
The visibility of the generated getters can be controlled by passing a hash with { visibility => imports } pairs, where imports is an array of import specifiers. An import specifier is a symbol (method name == dependency name) or a hash with { dependency_name => method_name } pairs (aliases). If there’s only one import specifier, its enclosing array can be omitted, e.g.:
include Services.mixin(private: :foo, protected: { :baz => :quux })
is equivalent to:
include Services.mixin(private: [:foo], protected: [{ :baz => :quux }])
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/wireless/registry.rb', line 81 def mixin(args) # normalize the supplied argument (array or hash) into a hash of # { visibility => exports } pairs, where `visibility` is a symbol and # `exports` is a hash of { dependency_name => method_name } pairs if args.is_a?(Array) args = { @default_visibility => args } elsif !args.is_a?(Hash) raise ArgumentError, "invalid mixin argument: expected array or hash, got: #{args.class}" end # slurp each array of name (symbol) or name => alias (hash) import # specifiers into a normalized hash of { dependency_name => method_name } # pairs, e.g.: # # before: # # [:foo, { :bar => :baz }, :quux] # # after: # # { :foo => :foo, :bar => :baz, :quux => :quux } # XXX transform_values requires ruby >= 2.5 args = DEFAULT_EXPORTS.merge(args).transform_values do |exports| exports = [exports] unless exports.is_a?(Array) exports.reduce({}) do |a, b| a.merge(b.is_a?(Hash) ? b : { b => b }) end end @module_cache.get!(args) { module_for(args) } end |
#singleton(name, klass = nil, &block) ⇒ Object Also known as: once
Registers a dependency which is only resolved the first time its value is fetched. On subsequent fetches, the cached value is returned.
50 51 52 |
# File 'lib/wireless/registry.rb', line 50 def singleton(name, klass = nil, &block) @registry[name.to_sym] = Resolver::Singleton.new(block || klass) end |