class SmartCore::Container::Registry

@api private @since 0.1.0 rubocop:disable Metrics/ClassLength

Constants

DEFAULT_ITERATION_YIELD_BEHAVIOUR

@return [Boolean]

@api private @since 0.4.0

DEFAULT_KEY_EXTRACTION_BEHAVIOUR

@return [Boolean]

@api private @since 0.4.0

DEFAULT_MEMOIZATION_BEHAVIOR

@return [Boolean]

@api private @since 0.3.0

Attributes

lock[R]

@return [Mutex]

@api private @since 0.1.0

registry[R]

@return [Hash<Symbol,SmartCore::Container::Entity>]

@api private @since 0.1.0

Public Class Methods

new() click to toggle source

@return [void]

@api private @since 0.1.0

# File lib/smart_core/container/registry.rb, line 38
def initialize
  @registry = {}
  @access_lock = SmartCore::Container::ArbitraryLock.new
end

Public Instance Methods

each(&block) click to toggle source

@param block [Block] @return [Enumerable]

@api private @since 0.1.0

# File lib/smart_core/container/registry.rb, line 101
def each(&block)
  thread_safe { enumerate(&block) }
end
each_dependency( root_dependency_name = nil, yield_all: DEFAULT_ITERATION_YIELD_BEHAVIOUR, &block ) click to toggle source

@param root_dependency_name [NilClass, String] @option yield_all [Boolean] @param block [Block] @return [Enumerable]

@api private @since 0.4.0

# File lib/smart_core/container/registry.rb, line 112
def each_dependency(
  root_dependency_name = nil,
  yield_all: DEFAULT_ITERATION_YIELD_BEHAVIOUR,
  &block
)
  thread_safe { iterate(root_dependency_name, yield_all: yield_all, &block) }
end
freeze!() click to toggle source

@return [void]

@api private @since 0.1.0

# File lib/smart_core/container/registry.rb, line 84
def freeze!
  thread_safe { freeze_state! }
end
frozen?() click to toggle source

@return [Boolean]

@api private @since 0.1.0

# File lib/smart_core/container/registry.rb, line 92
def frozen?
  thread_safe { state_frozen? }
end
hash_tree(resolve_dependencies: false) click to toggle source

@return [Hash<String|Symbol,SmartCore::Container::Entities::Base|Any>]

@api private @since 0.1.0

# File lib/smart_core/container/registry.rb, line 133
def hash_tree(resolve_dependencies: false)
  thread_safe { build_hash_tree(resolve_dependencies: resolve_dependencies) }
end
Also aliased as: to_h, to_hash
keys(all_variants: DEFAULT_KEY_EXTRACTION_BEHAVIOUR) click to toggle source

@option all_variants [Boolean] @return [Array<String>]

@api private @since 0.4.0

# File lib/smart_core/container/registry.rb, line 125
def keys(all_variants: DEFAULT_KEY_EXTRACTION_BEHAVIOUR)
  thread_safe { extract_keys(all_variants: all_variants) }
end
register_dependency(name, memoize: DEFAULT_MEMOIZATION_BEHAVIOR, &dependency_definition) click to toggle source

@param name [String, Symbol] @param memoize [Boolean] @param dependency_definition [Block] @return [void]

@api private @since 0.1.0 @version 0.3.0

# File lib/smart_core/container/registry.rb, line 60
def register_dependency(name, memoize: DEFAULT_MEMOIZATION_BEHAVIOR, &dependency_definition)
  thread_safe { add_dependency(name, dependency_definition, memoize) }
end
register_namespace( name, host_container = SmartCore::Container::NO_HOST_CONTAINER, &dependencies_definition ) click to toggle source

@param name [String, Symbol] @param host_container [NilClasss, SmartCore::Container] @param dependencies_definition [Block] @return [void]

@api private @since 0.1.0 @version 0.8.1

# File lib/smart_core/container/registry.rb, line 72
def register_namespace(
  name,
  host_container = SmartCore::Container::NO_HOST_CONTAINER,
  &dependencies_definition
)
  thread_safe { add_namespace(name, host_container, dependencies_definition) }
end
resolve(entity_path) click to toggle source

@param entity_path [String, Symbol] @return [SmartCore::Container::Entity]

@api private @since 0.1.0

# File lib/smart_core/container/registry.rb, line 48
def resolve(entity_path)
  thread_safe { fetch_entity(entity_path) }
end
to_h(resolve_dependencies: false)
Alias for: hash_tree
to_hash(resolve_dependencies: false)
Alias for: hash_tree

Private Instance Methods

add_dependency(dependency_name, dependency_definition, memoize) click to toggle source

@param dependency_name [String, Symbol] @param dependency_definition [Proc] @param memoize [Boolean] @return [SmartCore::Container::Entities::Dependency]

@raise [SmartCore::Container::DependencyOverNamespaceOverlapError]

@api private @since 0.1.0 @version 0.2.0

# File lib/smart_core/container/registry.rb, line 217
def add_dependency(dependency_name, dependency_definition, memoize)
  if state_frozen?
    raise(SmartCore::Container::FrozenRegistryError, 'Can not modify frozen registry!')
  end
  dependency_name = indifferently_accessable_name(dependency_name)
  prevent_namespace_overlap!(dependency_name)

  dependency_entity = SmartCore::Container::Entities::DependencyBuilder.build(
    dependency_name, dependency_definition, memoize
  )

  dependency_entity.tap { registry[dependency_name] = dependency_entity }
end
add_namespace(namespace_name, host_container, dependencies_definition) click to toggle source

@param namespace_name [String, Symbol] @param host_container [NilClass, SmartCore::Container] @param dependencies_definition [Proc] @return [SmartCore::Container::Entities::Namespace]

@raise [SmartCore::Container::NamespaceOverDependencyOverlapError]

@api private @since 0.1.0 @version 0.8.1 rubocop:disable Lint/EmptyBlock

# File lib/smart_core/container/registry.rb, line 242
def add_namespace(namespace_name, host_container, dependencies_definition)
  if state_frozen?
    raise(SmartCore::Container::FrozenRegistryError, 'Can not modify frozen registry!')
  end
  namespace_name = indifferently_accessable_name(namespace_name)
  dependencies_definition ||= proc {}
  prevent_dependency_overlap!(namespace_name)

  namespace_entity = begin
    fetch_entity(namespace_name)
  rescue SmartCore::Container::FetchError
    registry[namespace_name] = SmartCore::Container::Entities::NamespaceBuilder.build(
      namespace_name, host_container
    )
  end
  namespace_entity.tap { namespace_entity.append_definitions(dependencies_definition) }
end
build_hash_tree(resolve_dependencies: false) click to toggle source

@return [Hash<String|Symbol,SmartCore::Container::Entities::Base|Any>]

@api private @since 0.1.0

# File lib/smart_core/container/registry.rb, line 159
def build_hash_tree(resolve_dependencies: false)
  {}.tap do |tree|
    enumerate do |(entity_name, entity)|
      case entity
      when SmartCore::Container::Entities::Namespace
        tree[entity_name] = entity.reveal.hash_tree(resolve_dependencies: resolve_dependencies)
      when SmartCore::Container::Entities::Dependency
        tree[entity_name] = resolve_dependencies ? entity.reveal : entity
      end
    end
  end
end
enumerate(&block) click to toggle source

@param block @return [Enumerable]

@api private @since 0.1.0

# File lib/smart_core/container/registry.rb, line 189
def enumerate(&block)
  block_given? ? registry.each(&block) : registry.each
end
extract_keys(all_variants: DEFAULT_KEY_EXTRACTION_BEHAVIOUR) click to toggle source

@option all_variants [Boolean] @return [Array<String>]

@api private @since 0.4.0

# File lib/smart_core/container/registry.rb, line 305
def extract_keys(all_variants: DEFAULT_KEY_EXTRACTION_BEHAVIOUR)
  Set.new.tap do |dependency_names|
    iterate(yield_all: all_variants) do |dependency_name, _dependency|
      dependency_names << dependency_name
    end
  end.to_a
end
fetch_entity(entity_path) click to toggle source

@paramm entity_path [String, Symbol] @return [SmartCore::Container::Entity]

@api private @since 0.1.0 @version 0.1.0

# File lib/smart_core/container/registry.rb, line 199
def fetch_entity(entity_path)
  dependency_name = indifferently_accessable_name(entity_path)
  registry.fetch(dependency_name)
rescue KeyError
  error_message = "Entity with \"#{dependency_name}\" name does not exist"
  raise(SmartCore::Container::ResolvingError.new(error_message, path_part: dependency_name))
end
freeze_state!() click to toggle source

@return [void]

@api private @since 0.1.0

# File lib/smart_core/container/registry.rb, line 176
def freeze_state!
  registry.freeze.tap do
    enumerate do |(entity_name, entity)|
      entity.freeze! if entity.is_a?(SmartCore::Container::Entities::Namespace)
    end
  end
end
indifferently_accessable_name(name) click to toggle source

@param name [String, Symbol] @return [void]

@see [SmartCore::Container::KeyGuard]

@api private @since 0.1.0

# File lib/smart_core/container/registry.rb, line 320
def indifferently_accessable_name(name)
  SmartCore::Container::KeyGuard.indifferently_accessable_key(name)
end
iterate(root_dependency_name = nil, yield_all: DEFAULT_ITERATION_YIELD_BEHAVIOUR, &block) click to toggle source

@param root_dependency_name [String, NilClass] @param block [Block] @option yield_all [Boolean] @yield [dependency_name, dependency] @yield_param dependency_name [String] @yield_param dependency [Any] @return [Enumerable]

@api private @since 0.4.0

# File lib/smart_core/container/registry.rb, line 271
def iterate(root_dependency_name = nil, yield_all: DEFAULT_ITERATION_YIELD_BEHAVIOUR, &block)
  enumerator = Enumerator.new do |yielder|
    registry.each_pair do |dependency_name, dependency|
      final_dependency_name =
        if root_dependency_name
          "#{root_dependency_name}" \
          "#{SmartCore::Container::DependencyResolver::PATH_PART_SEPARATOR}" \
          "#{dependency_name}"
        else
          dependency_name
        end

      case dependency
      when SmartCore::Container::Entities::Dependency
        yielder.yield(final_dependency_name, dependency.reveal)
      when SmartCore::Container::Entities::Namespace
        yielder.yield(final_dependency_name, dependency.reveal) if yield_all
        dependency.reveal.registry.each_dependency(
          final_dependency_name,
          yield_all: yield_all,
          &block
        )
      end
    end
  end

  block_given? ? enumerator.each(&block) : enumerator.each
end
prevent_dependency_overlap!(namespace_name) click to toggle source

@param namespace_name [String] @return [void]

@api private @since 0.1.0

# File lib/smart_core/container/registry.rb, line 340
def prevent_dependency_overlap!(namespace_name)
  SmartCore::Container::DependencyCompatability::Registry.prevent_dependency_overlap!(
    self, namespace_name
  )
end
prevent_namespace_overlap!(dependency_name) click to toggle source

@param dependency_name [String] @return [void]

@api private @since 0.1.0

# File lib/smart_core/container/registry.rb, line 329
def prevent_namespace_overlap!(dependency_name)
  SmartCore::Container::DependencyCompatability::Registry.prevent_namespace_overlap!(
    self, dependency_name
  )
end
state_frozen?() click to toggle source

@return [Boolean]

@api private @since 0.1.0

# File lib/smart_core/container/registry.rb, line 151
def state_frozen?
  registry.frozen?
end
thread_safe(&block) click to toggle source

@param block [Proc] @return [Any]

@api private @since 0.1.0

# File lib/smart_core/container/registry.rb, line 351
def thread_safe(&block)
  @access_lock.thread_safe(&block)
end