Class: Dry::System::Provider::Source

Inherits:
Object
  • Object
show all
Extended by:
Core::ClassAttributes
Defined in:
lib/dry/system/provider/source.rb

Overview

A provider’s source provides the specific behavior for a given provider to serve its purpose.

Sources should be subclasses of ‘Dry::System::Source::Provider`, with instance methods for each lifecycle step providing their behavior: #prepare, #start, and #stop.

Inside each of these methods, you should create and configure your provider’s objects as required, and then #register them with the #provider_container. When the provider’s lifecycle steps are run (via Dry::System::Provider), these registered components will be merged into the target container.

You can prepare a provider’s source in two ways:

  1. Passing a bock when registering the provider, which is then evaluated via SourceDSL to prepare the provider subclass. This approach is easiest for simple providers.

  2. Manually creare your own subclass of Dry::System::Provider and implement your own instance methods for the lifecycle steps (you should not implement your own ‘#initialize`). This approach may be useful for more complex providers.

Constant Summary collapse

CALLBACK_MAP =
Hash.new { |h, k| h[k] = [] }.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(provider_container:, target_container:, &block) ⇒ Source

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of Source.



123
124
125
126
127
128
129
# File 'lib/dry/system/provider/source.rb', line 123

def initialize(provider_container:, target_container:, &block)
  super()
  @callbacks = {before: CALLBACK_MAP.dup, after: CALLBACK_MAP.dup}
  @provider_container = provider_container
  @target_container = target_container
  instance_exec(&block) if block
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object (private)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



261
262
263
264
265
266
267
# File 'lib/dry/system/provider/source.rb', line 261

def method_missing(name, *args, &block)
  if container.key?(name)
    container[name]
  else
    super
  end
end

Instance Attribute Details

#callbacksObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



87
88
89
# File 'lib/dry/system/provider/source.rb', line 87

def callbacks
  @callbacks
end

#provider_containerDry::Container (readonly) Also known as: container

Returns the provider’s own container for the provider.

This container is namespaced based on the provider’s ‘namespace:` configuration.

Registered components in this container will be merged into the target container after the ‘prepare` and `start` lifecycle steps.

Returns:

  • (Dry::Container)

See Also:



102
103
104
# File 'lib/dry/system/provider/source.rb', line 102

def provider_container
  @provider_container
end

#target_containerDry::System::Container (readonly) Also known as: target

Returns the target container for the provider.

This is the container with which the provider is registered (via Container.register_provider).

Registered components from the provider’s container will be merged into this container after the ‘prepare` and `start` lifecycle steps.



119
120
121
# File 'lib/dry/system/provider/source.rb', line 119

def target_container
  @target_container
end

Class Method Details

.for(name:, group: nil, &block) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new Dry::System::Provider::Source subclass with its behavior supplied by the given block, which is evaluated using Dry::System::Provider::SourceDSL.



40
41
42
43
44
45
46
# File 'lib/dry/system/provider/source.rb', line 40

def for(name:, group: nil, &block)
  Class.new(self) { |klass|
    klass.source_name name
    klass.source_group group
    SourceDSL.evaluate(klass, &block) if block
  }
end

.inherited(subclass) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/dry/system/provider/source.rb', line 48

def inherited(subclass)
  super

  # Include Dry::Configurable only when first subclassing to ensure that
  # distinct Source subclasses do not share settings.
  #
  # The superclass check here allows deeper Source class hierarchies to be
  # created without running into a Dry::Configurable::AlreadyIncluded error.
  if subclass.superclass == Source
    subclass.include Dry::Configurable
  end
end

.inspectObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



75
76
77
# File 'lib/dry/system/provider/source.rb', line 75

def inspect
  to_s
end

.nameObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



62
63
64
65
66
67
# File 'lib/dry/system/provider/source.rb', line 62

def name
  source_str = source_name
  source_str = "#{source_group}->#{source_str}" if source_group

  "Dry::System::Provider::Source[#{source_str}]"
end

.to_sObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



70
71
72
# File 'lib/dry/system/provider/source.rb', line 70

def to_s
  "#<#{name}>"
end

Instance Method Details

#after(step_name, &block) ⇒ self

Registers an “after” callback for the given lifecycle step.

The given block will be run after the lifecycle step method is run. The block will be evaluated in the context of the instance of this source.

Parameters:

  • step_name (Symbol)
  • block (Proc)

    the callback block

Returns:

  • (self)

See Also:



217
218
219
220
# File 'lib/dry/system/provider/source.rb', line 217

def after(step_name, &block)
  callbacks[:after][step_name] << block
  self
end

#before(step_name, &block) ⇒ self

Registers a “before” callback for the given lifecycle step.

The given block will be run before the lifecycle step method is run. The block will be evaluated in the context of the instance of this source.

Parameters:

  • step_name (Symbol)
  • block (Proc)

    the callback block

Returns:

  • (self)

See Also:



199
200
201
202
# File 'lib/dry/system/provider/source.rb', line 199

def before(step_name, &block)
  callbacks[:before][step_name] << block
  self
end

#inspectString

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a string containing a human-readable representation of the provider.

Returns:

  • (String)


136
137
138
139
140
141
142
# File 'lib/dry/system/provider/source.rb', line 136

def inspect
  ivars = instance_variables.map { |ivar|
    "#{ivar}=#{instance_variable_get(ivar).inspect}"
  }.join(" ")

  "#<#{self.class.name} #{ivars}>"
end

#preparevoid

This method returns an undefined value.

Runs the behavior for the “prepare” lifecycle step.

This should be implemented by your source subclass or specified by ‘SourceDSL#prepare` when registering a provider using a block.



154
# File 'lib/dry/system/provider/source.rb', line 154

def prepare; end

#run_callback(hook, step) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



223
224
225
226
227
# File 'lib/dry/system/provider/source.rb', line 223

def run_callback(hook, step)
  callbacks[hook][step].each do |callback|
    instance_eval(&callback)
  end
end

#startvoid

This method returns an undefined value.

Runs the behavior for the “start” lifecycle step.

This should be implemented by your source subclass or specified by ‘SourceDSL#start` when registering a provider using a block.

You can presume that #prepare has already run by the time this method is called.



169
# File 'lib/dry/system/provider/source.rb', line 169

def start; end

#stopvoid

This method returns an undefined value.

Runs the behavior for the “stop” lifecycle step.

This should be implemented by your source subclass or specified by ‘SourceDSL#stop` when registering a provider using a block.

You can presume that #prepare and #start have already run by the time this method is called.



184
# File 'lib/dry/system/provider/source.rb', line 184

def stop; end