Class: Dry::Component::Container

Inherits:
Object
  • Object
show all
Extended by:
Dry::Configurable, Dry::Container::Mixin
Defined in:
lib/dry/component/container.rb

Class Method Summary collapse

Class Method Details

.auto_register!(dir, &_block) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/dry/component/container.rb', line 72

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', '')
    loader.load(component_path).tap do |component|
      next if key?(component.identifier)

      Kernel.require component.path

      if block_given?
        register(component.identifier, yield(component.constant))
      else
        register(component.identifier) { component.instance }
      end
    end
  end

  self
end

.boot(name) ⇒ Object



109
110
111
# File 'lib/dry/component/container.rb', line 109

def self.boot(name)
  require "#{config.core_dir}/boot/#{name}"
end

.boot!(name) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/dry/component/container.rb', line 93

def self.boot!(name)
  check_component_identifier!(name)

  return self unless booted?(name)

  boot(name)

  finalizers[name].tap do |finalizer|
    finalizer.() if finalizer
  end

  booted[name] = true

  self
end

.bootedObject



186
187
188
# File 'lib/dry/component/container.rb', line 186

def self.booted
  @booted ||= {}
end

.booted?(name) ⇒ Boolean

Returns:

  • (Boolean)


113
114
115
# File 'lib/dry/component/container.rb', line 113

def self.booted?(name)
  !booted.key?(name)
end

.configure(&block) ⇒ Object



25
26
27
28
29
30
31
# File 'lib/dry/component/container.rb', line 25

def self.configure(&block)
  super(&block)

  load_paths!(config.core_dir)

  self
end

.finalize(name, &block) ⇒ Object



44
45
46
# File 'lib/dry/component/container.rb', line 44

def self.finalize(name, &block)
  finalizers[name] = proc { block.(self) }
end

.finalize! {|_self| ... } ⇒ Object

Yields:

  • (_self)

Yield Parameters:



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/dry/component/container.rb', line 48

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

.finalizersObject



190
191
192
# File 'lib/dry/component/container.rb', line 190

def self.finalizers
  @finalizers ||= {}
end

.import(other) ⇒ Object



33
34
35
36
37
38
39
40
41
42
# File 'lib/dry/component/container.rb', line 33

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

.importsObject



194
195
196
# File 'lib/dry/component/container.rb', line 194

def self.imports
  @imports ||= {}
end

.injector(options = {}) ⇒ Object



68
69
70
# File 'lib/dry/component/container.rb', line 68

def self.injector(options = {})
  Injector.new(self, options: options)
end

.load_component(key) ⇒ Object



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/dry/component/container.rb', line 125

def self.load_component(key)
  return self if key?(key)

  component = loader.load(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
    begin
      require_component(component) { |klass| register(key) { klass.new } }
    rescue FileNotFoundError => e
      if config.default_namespace
        load_component("#{config.default_namespace}#{config.namespace_separator}#{component.identifier}")
      else
        raise e
      end
    end
  end

  self
end

.load_pathsObject



182
183
184
# File 'lib/dry/component/container.rb', line 182

def self.load_paths
  @load_paths ||= []
end

.load_paths!(*dirs) ⇒ Object



169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/dry/component/container.rb', line 169

def self.load_paths!(*dirs)
  dirs.map(&:to_s).each do |dir|
    path = root.join(dir)

    next if load_paths.include?(path)

    load_paths << path
    $LOAD_PATH.unshift(path.to_s)
  end

  self
end

.loaderObject



64
65
66
# File 'lib/dry/component/container.rb', line 64

def self.loader
  @loader ||= config.loader.new(config)
end

.require(*paths) ⇒ Object



117
118
119
120
121
122
123
# File 'lib/dry/component/container.rb', line 117

def self.require(*paths)
  paths.flat_map { |path|
    path.to_s.include?('*') ? Dir[root.join(path)] : root.join(path)
  }.each { |path|
    Kernel.require path.to_s
  }
end

.require_component(component, &block) ⇒ Object



154
155
156
157
158
159
160
161
162
163
# File 'lib/dry/component/container.rb', line 154

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 FileNotFoundError, "could not resolve require file for #{component.identifier}"
  end
end

.rootObject



165
166
167
# File 'lib/dry/component/container.rb', line 165

def self.root
  config.root
end