lib/dry/component/container.rb in dry-component-0.0.1 vs lib/dry/component/container.rb in dry-component-0.1.0
- old
+ new
@@ -1,77 +1,96 @@
+require 'pathname'
require 'inflecto'
+
require 'dry-container'
-require 'dry-auto_inject'
+require 'dry/component/injector'
require 'dry/component/loader'
require 'dry/component/config'
module Dry
module Component
class Container
extend Dry::Container::Mixin
setting :env
+ setting :name
setting :root, Pathname.pwd.freeze
setting :core_dir, 'core'.freeze
setting :auto_register
setting :options
+ setting :loader, Dry::Component::Loader
+ def self.inherited(subclass)
+ super
+ subclass.const_set :Inject, subclass.injector
+ end
+
def self.configure(env = config.env, &block)
return self if configured?
super() do |config|
yield(config) if block
- config.options = Config.load(root, env)
+ config.options = Config.load(root, config.name, env)
end
load_paths!(config.core_dir)
@configured = true
self
end
+ def self.import(other)
+ case other
+ when Dry::Container::Namespace then super
+ when Hash then imports.update(other)
+ else
+ if other < Component::Container
+ imports.update(other.config.name => other)
+ end
+ end
+ end
+
def self.options
config.options
end
def self.finalize(name, &block)
- finalizers[name] = block
+ finalizers[name] = proc { block.(self) }
end
def self.configured?
@configured
end
def self.finalize!(&_block)
yield(self) if block_given?
+ imports.each do |ns, container|
+ import_container(ns, container.finalize!)
+ end
+
Dir[root.join("#{config.core_dir}/boot/**/*.rb")].each do |path|
boot!(File.basename(path, '.rb').to_sym)
end
auto_register.each(&method(:auto_register!)) if auto_register?
freeze
end
- def self.import_module
- auto_inject = Dry::AutoInject(self)
-
- -> *keys {
- keys.each { |key| load_component(key) unless key?(key) }
- auto_inject[*keys]
- }
+ def self.injector
+ Injector.new(self)
end
def self.auto_register!(dir, &_block)
dir_root = root.join(dir.to_s.split('/')[0])
Dir["#{root}/#{dir}/**/*.rb"].each do |path|
component_path = path.to_s.gsub("#{dir_root}/", '').gsub('.rb', '')
- Component.Loader(component_path).tap do |component|
+ config.loader.new(component_path).tap do |component|
next if key?(component.identifier)
Kernel.require component.path
if block_given?
@@ -85,50 +104,65 @@
self
end
def self.boot!(name)
check_component_identifier!(name)
+
return self unless booted?(name)
+
boot(name)
- self
- end
- def self.boot(name)
- require "#{config.core_dir}/boot/#{name}.rb"
-
finalizers[name].tap do |finalizer|
finalizer.() if finalizer
end
booted[name] = true
+
+ self
end
+ def self.boot(name)
+ require "#{config.core_dir}/boot/#{name}"
+ end
+
def self.booted?(name)
!booted.key?(name)
end
def self.require(*paths)
paths.flat_map { |path|
- path.include?('*') ? Dir[root.join(path)] : root.join(path)
+ path.to_s.include?('*') ? Dir[root.join(path)] : root.join(path)
}.each { |path|
Kernel.require path.to_s
}
end
def self.load_component(key)
- require_component(key) { |klass| register(key) { klass.new } }
+ component = config.loader.new(key)
+ src_key = component.namespaces[0]
+
+ if imports.key?(src_key)
+ src_container = imports[src_key]
+
+ src_container.load_component(
+ (component.namespaces - [src_key]).map(&:to_s).join('.')
+ )
+
+ import_container(src_key, src_container)
+ else
+ require_component(component) { |klass| register(key) { klass.new } }
+ end
end
- def self.require_component(key, &block)
- component = Component.Loader(key)
+ def self.require_component(component, &block)
path = load_paths.detect { |p| p.join(component.file).exist? }
if path
Kernel.require component.path
yield(component.constant) if block
else
- fail ArgumentError, "could not resolve require file for #{key}"
+ fail ArgumentError, "could not resolve require file for #{component.identifier}"
end
end
def self.root
config.root
@@ -153,10 +187,22 @@
def self.finalizers
@finalizers ||= {}
end
+ def self.imports
+ @imports ||= {}
+ end
+
private
+
+ def self.import_container(ns, container)
+ items = container._container.each_with_object({}) { |(key, item), res|
+ res[[ns, key].join(config.namespace_separator)] = item
+ }
+
+ _container.update(items)
+ end
def self.auto_register
Array(config.auto_register)
end