lib/dry/system/container.rb in dry-system-0.12.0 vs lib/dry/system/container.rb in dry-system-0.13.0

- old
+ new

@@ -1,5 +1,7 @@ +# frozen_string_literal: true + require 'pathname' require 'dry-auto_inject' require 'dry-configurable' require 'dry-container' @@ -71,22 +73,30 @@ extend Dry::System::Plugins setting :name setting :default_namespace setting(:root, Pathname.pwd.freeze) { |path| Pathname(path) } - setting :system_dir, 'system'.freeze - setting :registrations_dir, 'container'.freeze + setting :system_dir, 'system' + setting :registrations_dir, 'container' setting :auto_register, [] setting :inflector, Dry::Inflector.new setting :loader, Dry::System::Loader setting :booter, Dry::System::Booter setting :auto_registrar, Dry::System::AutoRegistrar setting :manual_registrar, Dry::System::ManualRegistrar setting :importer, Dry::System::Importer - setting(:components, {}, reader: true) { |v| v.dup } + setting(:components, {}, reader: true, &:dup) class << self + def strategies(value = nil) + if value + @strategies = value + else + @strategies ||= Dry::AutoInject::Strategies + end + end + extend Dry::Core::Deprecations['Dry::System::Container'] # Configures the container # # @example @@ -137,11 +147,13 @@ def import(other) case other when Hash then importer.register(other) when Dry::Container::Namespace then super else - raise ArgumentError, "+other+ must be a hash of names and systems, or a Dry::Container namespace" + raise ArgumentError, <<-STR + +other+ must be a hash of names and systems, or a Dry::Container namespace + STR end end # Registers finalization function for a bootable component # @@ -216,20 +228,21 @@ # @return [self] # # @api public def boot(name, opts = {}, &block) if components.key?(name) - raise DuplicatedComponentKeyError, "Bootable component #{name.inspect} was already registered" + raise DuplicatedComponentKeyError, <<-STR + Bootable component #{name.inspect} was already registered + STR end component = if opts[:from] boot_external(name, opts, &block) else boot_local(name, opts, &block) end - self components[name] = component end deprecate :finalize, :boot @@ -244,11 +257,13 @@ component end # @api private def boot_local(identifier, namespace: nil, &block) - component = Components::Bootable.new(identifier, container: self, namespace: namespace, &block) + component = Components::Bootable.new( + identifier, container: self, namespace: namespace, &block + ) booter.register_component(component) component end @@ -379,10 +394,11 @@ # # @api public def load_paths!(*dirs) dirs.map(&root.method(:join)).each do |path| next if load_paths.include?(path) + load_paths << path $LOAD_PATH.unshift(path.to_s) end self end @@ -457,11 +473,11 @@ # MyApp['user_repo].db # instance under 'persistence.db' key # # @param options [Hash] injector options # # @api public - def injector(options = {}) + def injector(options = { strategies: strategies }) Dry::AutoInject(self, options) end # Requires one or more files relative to the container's root # @@ -475,11 +491,11 @@ # @param paths [Array<String>] one or more paths, supports globs too # # @api public def require_from_root(*paths) paths.flat_map { |path| - path.to_s.include?('*') ? Dir[root.join(path)] : root.join(path) + path.to_s.include?('*') ? ::Dir[root.join(path)].sort : root.join(path) }.each { |path| require path.to_s } end @@ -500,16 +516,41 @@ def root config.root end # @api public - def resolve(key) - load_component(key) unless finalized? + def resolve(key, &block) + load_component(key, &block) unless finalized? super end + alias_method :registered?, :key? + # + # @!method registered?(key) + # Whether a +key+ is registered (doesn't trigger loading) + # @param [String,Symbol] key Identifier + # @return [Boolean] + # @api public + # + + # Check if identifier is registered. + # If not, try to load the component + # + # @param [String,Symbol] key Identifier + # @return [Boolean] + # + # @api public + def key?(key) + if finalized? + registered?(key) + else + registered?(key) || resolve(key) { return false } + true + end + end + # @api private def load_paths @load_paths ||= [] end @@ -547,22 +588,20 @@ identifier, loader: config.loader, namespace: config.default_namespace, separator: config.namespace_separator, inflector: config.inflector, - **options, + **options ) end end # @api private def require_component(component) - return if key?(component.identifier) + return if registered?(component.identifier) - unless component.file_exists?(load_paths) - raise FileNotFoundError, component - end + raise FileNotFoundError, component unless component.file_exists?(load_paths) require_path(component.path) yield end @@ -577,12 +616,12 @@ def require_path(path) require path end # @api private - def load_component(key) - return self if key?(key) + def load_component(key, &block) + return self if registered?(key) component(key).tap do |component| if component.boot? booter.start(component) else @@ -592,13 +631,11 @@ booter.start(bootable_dep) elsif importer.key?(root_key) load_imported_component(component.namespaced(root_key)) end - if !key?(key) - load_local_component(component) - end + load_local_component(component, &block) unless registered?(key) end end self end @@ -608,11 +645,11 @@ hooks[event] << block end # @api private def hooks - @__hooks__ ||= Hash.new { |h, k| h[k] = [] } + @hooks ||= Hash.new { |h, k| h[k] = [] } end # @api private def inherited(klass) new_hooks = Container.hooks.dup @@ -620,27 +657,29 @@ hooks.each do |event, blocks| new_hooks[event].concat(blocks) new_hooks[event].concat(klass.hooks[event]) end - klass.instance_variable_set(:@__hooks__, new_hooks) + klass.instance_variable_set(:@hooks, new_hooks) super end private # @api private - def load_local_component(component, default_namespace_fallback = false) + def load_local_component(component, default_namespace_fallback = false, &block) if booter.bootable?(component) || component.file_exists?(load_paths) booter.boot_dependency(component) unless finalized? require_component(component) do register(component.identifier) { component.instance } end elsif !default_namespace_fallback - load_local_component(component.prepend(config.default_namespace), true) + load_local_component(component.prepend(config.default_namespace), true, &block) elsif manual_registrar.file_exists?(component) manual_registrar.(component) + elsif block_given? + yield else raise ComponentLoadError, component end end