lib/hanami/application.rb in hanami-2.0.0.alpha5 vs lib/hanami/application.rb in hanami-2.0.0.alpha6
- old
+ new
@@ -5,21 +5,21 @@
require "hanami/configuration"
require "pathname"
require "rack"
require "zeitwerk"
require_relative "slice"
-require_relative "application/autoloader/inflector_adapter"
module Hanami
# Hanami application class
#
# @since 2.0.0
class Application
@_mutex = Mutex.new
class << self
def inherited(klass)
+ super
@_mutex.synchronize do
klass.class_eval do
@_mutex = Mutex.new
@_configuration = Hanami::Configuration.new(application_name: name, env: Hanami.env)
@@ -37,47 +37,50 @@
#
# rubocop:disable Metrics/ModuleLength
module ClassMethods
def self.extended(klass)
klass.class_eval do
- @inited = @booted = false
+ @prepared = @booted = false
end
end
def configuration
@_configuration
end
- alias config configuration
+ alias_method :config, :configuration
- def init # rubocop:disable Metrics/MethodLength
- return self if inited?
+ def prepare(provider_name = nil)
+ if provider_name
+ container.prepare(provider_name)
+ return self
+ end
+ return self if prepared?
+
configuration.finalize!
- @autoloader = Zeitwerk::Loader.new
- autoloader.inflector = Autoloader::InflectorAdapter.new(inflector)
-
load_settings
+ @autoloader = Zeitwerk::Loader.new
@container = prepare_container
@deps_module = prepare_deps_module
load_slices
- slices.values.each(&:init)
+ slices.each_value(&:prepare)
slices.freeze
- autoloader.setup
+ @autoloader.setup
- @inited = true
+ @prepared = true
self
end
def boot(&block)
return self if booted?
- init
+ prepare
container.finalize!(&block)
slices.values.each(&:boot)
@@ -87,38 +90,38 @@
def shutdown
container.shutdown!
end
- def inited?
- @inited
+ def prepared?
+ @prepared
end
def booted?
@booted
end
def autoloader
- raise "Application not init'ed" unless defined?(@autoloader)
+ raise "Application not yet prepared" unless defined?(@autoloader)
@autoloader
end
def container
- raise "Application not init'ed" unless defined?(@container)
+ raise "Application not yet prepared" unless defined?(@container)
@container
end
def deps
- raise "Application not init'ed" unless defined?(@deps_module)
+ raise "Application not yet prepared" unless defined?(@deps_module)
@deps_module
end
def router
- raise "Application not init'ed" unless inited?
+ raise "Application not yet prepared" unless prepared?
@_mutex.synchronize do
@_router ||= load_router
end
end
@@ -137,40 +140,36 @@
slice = Slice.new(self, name: name, **slice_args)
slice.namespace.const_set :Slice, slice if slice.namespace # rubocop:disable Style/SafeNavigation
slices[name.to_sym] = slice
end
- def register(*args, **opts, &block)
- container.register(*args, **opts, &block)
+ def register(...)
+ container.register(...)
end
- def register_bootable(*args, **opts, &block)
- container.boot(*args, **opts, &block)
+ def register_provider(...)
+ container.register_provider(...)
end
- def init_bootable(*args)
- container.init(*args)
+ def start(...)
+ container.start(...)
end
- def start_bootable(*args)
- container.start(*args)
+ def key?(...)
+ container.key?(...)
end
- def key?(*args)
- container.key?(*args)
- end
-
def keys
container.keys
end
- def [](*args)
- container[*args]
+ def [](...)
+ container.[](...)
end
- def resolve(*args)
- container.resolve(*args)
+ def resolve(...)
+ container.resolve(...)
end
def settings
@_settings ||= load_settings
end
@@ -199,11 +198,11 @@
configuration.inflector
end
# @api private
def component_provider(component)
- raise "Hanami.application must be inited before detecting providers" unless inited?
+ raise "Hanami.application must be prepared before detecting providers" unless prepared?
# [Admin, Main, MyApp] or [MyApp::Admin, MyApp::Main, MyApp]
providers = slices.values + [self]
component_class = component.is_a?(Class) ? component : component.class
@@ -219,58 +218,51 @@
def prepare_base_load_path
base_path = File.join(root, "lib")
$LOAD_PATH.unshift base_path unless $LOAD_PATH.include?(base_path)
end
+ # rubocop:disable Metrics/AbcSize
def prepare_container
- define_container.tap do |container|
- configure_container container
- end
- end
+ container =
+ begin
+ require "#{application_name}/container"
+ namespace.const_get :Container
+ rescue LoadError, NameError
+ namespace.const_set :Container, Class.new(Dry::System::Container)
+ end
- def prepare_deps_module
- define_deps_module
- end
-
- def define_container
- require "#{application_name}/container"
- namespace.const_get :Container
- rescue LoadError, NameError
- namespace.const_set :Container, Class.new(Dry::System::Container)
- end
-
- # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
- def configure_container(container)
container.use :env, inferrer: -> { Hanami.env }
+ container.use :zeitwerk, loader: autoloader, run_setup: false, eager_load: false
container.use :notifications
- container.configure do |config|
- config.inflector = configuration.inflector
+ container.config.root = configuration.root
+ container.config.inflector = configuration.inflector
- config.root = configuration.root
- config.bootable_dirs = [
- "config/boot",
- Pathname(__dir__).join("application/container/boot").realpath,
- ]
+ container.config.provider_dirs = [
+ "config/providers",
+ Pathname(__dir__).join("application/container/providers").realpath,
+ ]
- config.component_dirs.loader = Dry::System::Loader::Autoloading
- config.component_dirs.add_to_load_path = false
- end
-
# Autoload classes defined in lib/[app_namespace]/
if root.join("lib", namespace_path).directory?
- autoloader.push_dir(root.join("lib", namespace_path), namespace: namespace)
+ container.autoloader.push_dir(root.join("lib", namespace_path), namespace: namespace)
end
- # Add lib/ to to the $LOAD_PATH so other files there (outside the app namespace)
- # are require-able
+ # Add lib/ to to the $LOAD_PATH so any files there (outside the app namespace) can
+ # be required
container.add_to_load_path!("lib") if root.join("lib").directory?
+ container.configured!
+
container
end
- # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
+ # rubocop:enable Metrics/AbcSize
+ def prepare_deps_module
+ define_deps_module
+ end
+
def define_deps_module
require "#{application_name}/deps"
namespace.const_get :Deps
rescue LoadError, NameError
namespace.const_set :Deps, container.injector
@@ -284,11 +276,10 @@
def slices_path
File.join(root, config.slices_dir)
end
- # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
def load_slice(slice_path)
slice_path = Pathname(slice_path)
slice_name = slice_path.relative_path_from(Pathname(slices_path)).to_s
slice_const_name = inflector.camelize(slice_name)
@@ -306,10 +297,9 @@
slice_name,
namespace: slice_module,
root: slice_path.realpath
)
end
- # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
def load_settings
require_relative "application/settings"
prepare_base_load_path