Class: Dry::System::Provider

Inherits:
Object
  • Object
show all
Defined in:
lib/dry/system/provider.rb,
lib/dry/system/provider/source.rb,
lib/dry/system/provider/source_dsl.rb

Overview

Providers can prepare and register one or more objects and typically work with third party code. A typical provider might be for a database library, or an API client.

The particular behavior for any provider is defined in a Source, which is a subclass created when you run Container.register_provider or register_provider_source. The Source provides this behavior through methods for each of the steps in the provider lifecycle: ‘prepare`, `start`, and `run`. These methods typically create and configure various objects, then register them with the #provider_container.

The Provider manages this lifecycle by implementing common behavior around the lifecycle steps, such as running step callbacks, and only running steps when appropriate for the current status of the lifecycle.

Providers can be registered via Container.register_provider.

Examples:

Simple provider

class App < Dry::System::Container
  register_provider(:logger) do
    prepare do
      require "logger"
    end

    start do
      register(:logger, Logger.new($stdout))
    end
  end
end

App[:logger] # returns configured logger

Using an external Provider Source

class App < Dry::System::Container
  register_provider(:logger, from: :some_external_provider_source) do
    configure do |config|
      config.log_level = :debug
    end

    after :start do
      register(:my_extra_logger, resolve(:logger))
    end
  end
end

App[:my_extra_logger] # returns the extra logger registered in the callback

Defined Under Namespace

Classes: Source, SourceDSL

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name:, namespace: nil, target_container:, source_class:, &block) ⇒ Provider

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 Provider.



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/dry/system/provider.rb', line 130

def initialize(name:, namespace: nil, target_container:, source_class:, &block) # rubocop:disable Style/KeywordParametersOrder
  @name = name
  @namespace = namespace
  @target_container = target_container

  @provider_container = build_provider_container
  @statuses = []
  @step_running = nil

  @source = source_class.new(
    provider_container: provider_container,
    target_container: target_container,
    &block
  )
end

Instance Attribute Details

#nameSymbol (readonly)

Returns the provider’s unique name.

Returns:

  • (Symbol)


60
61
62
# File 'lib/dry/system/provider.rb', line 60

def name
  @name
end

#namespaceSymbol, String (readonly)

Returns the default namespace for the provider’s container keys.

Returns:

  • (Symbol, String)


67
68
69
# File 'lib/dry/system/provider.rb', line 67

def namespace
  @namespace
end

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

Returns the container for the provider.

This is where the provider’s source will register its components, which are then later marged into the target container after the ‘prepare` and `start` lifecycle steps.

Returns:

  • (Dry::Core::Container)


96
97
98
# File 'lib/dry/system/provider.rb', line 96

def provider_container
  @provider_container
end

#sourceDry::System::Provider::Source (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.

Returns the provider’s source

The source provides the specific behavior for the provider via methods implementing the lifecycle steps.

The provider’s source is defined when registering a provider with the container, or an external provider source.



127
128
129
# File 'lib/dry/system/provider.rb', line 127

def source
  @source
end

#statusesArray<Symbol> (readonly)

Returns an array of lifecycle steps that have been run.

Examples:

provider.statuses # => [:prepare, :start]

Returns:

  • (Array<Symbol>)


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

def statuses
  @statuses
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.



110
111
112
# File 'lib/dry/system/provider.rb', line 110

def target_container
  @target_container
end

Instance Method Details

#prepareself

Runs the ‘prepare` lifecycle step.

Also runs any callbacks for the step, and then merges any registered components from the provider container into the target container.

Returns:

  • (self)


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

def prepare
  run_step(:prepare)
end

#prepared?Boolean

Returns true if the provider’s ‘prepare` lifecycle step has run

Returns:

  • (Boolean)


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

def prepared?
  statuses.include?(:prepare)
end

#startself

Runs the ‘start` lifecycle step.

Also runs any callbacks for the step, and then merges any registered components from the provider container into the target container.

Returns:

  • (self)


166
167
168
169
# File 'lib/dry/system/provider.rb', line 166

def start
  run_step(:prepare)
  run_step(:start)
end

#started?Boolean

Returns true if the provider’s ‘start` lifecycle step has run

Returns:

  • (Boolean)


194
195
196
# File 'lib/dry/system/provider.rb', line 194

def started?
  statuses.include?(:start)
end

#stopself

Runs the ‘stop` lifecycle step.

Also runs any callbacks for the step.

Returns:

  • (self)


178
179
180
181
182
# File 'lib/dry/system/provider.rb', line 178

def stop
  return self unless started?

  run_step(:stop)
end

#stopped?Boolean

Returns true if the provider’s ‘stop` lifecycle step has run

Returns:

  • (Boolean)


201
202
203
# File 'lib/dry/system/provider.rb', line 201

def stopped?
  statuses.include?(:stop)
end