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.



128
129
130
131
132
133
134
# File 'lib/dry/system/provider/source.rb', line 128

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.



266
267
268
269
270
271
272
# File 'lib/dry/system/provider/source.rb', line 266

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.



89
90
91
# File 'lib/dry/system/provider/source.rb', line 89

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:



104
105
106
# File 'lib/dry/system/provider/source.rb', line 104

def provider_container
  @provider_container
end

#target_containerDry::System::Container (readonly)

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.



121
122
123
# File 'lib/dry/system/provider/source.rb', line 121

def target_container
  @target_container
end

Class Method Details

.for(name:, group: nil, superclass: 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
47
48
49
50
51
52
53
54
55
56
# File 'lib/dry/system/provider/source.rb', line 40

def for(name:, group: nil, superclass: nil, &block)
  superclass ||= self

  Class.new(superclass) { |klass|
    klass.source_name name
    klass.source_group group

    name_with_group = group ? "#{group}->#{name}" : name
    klass.instance_eval <<~RUBY, __FILE__, __LINE__ + 1
      def name
        "#{superclass.name}[#{name_with_group}]"
      end
    RUBY

    SourceDSL.evaluate(klass, &block) if block
  }
end

.inherited(subclass) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/dry/system/provider/source.rb', line 58

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.



77
78
79
# File 'lib/dry/system/provider/source.rb', line 77

def inspect
  to_s
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.



72
73
74
# File 'lib/dry/system/provider/source.rb', line 72

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:



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

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:



204
205
206
207
# File 'lib/dry/system/provider/source.rb', line 204

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)


141
142
143
144
145
146
147
# File 'lib/dry/system/provider/source.rb', line 141

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.



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

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.



228
229
230
231
232
# File 'lib/dry/system/provider/source.rb', line 228

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.



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

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.



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

def stop; end

#targetObject

See Also:



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

def target = target_container