Module: Flows::Plugin::DependencyInjector
- Includes:
- InheritanceCallback, Util::InheritableSingletonVars::DupStrategy.make_module( '@dependencies' => {} ), Util::PrependToClass.make_module do def initialize(*args, **kwargs, &block) # rubocop:disable Metrics/MethodLength if @__dependencies_injected__ if kwargs.empty? # https://bugs.ruby-lang.org/issues/14415 super(*args, &block) else super(*args, **kwargs, &block) end return end @__dependencies_injected__ = true klass = self.class DependencyList.new( klass: klass, definitions: klass.dependencies, provided_values: kwargs[:dependencies].dup || {} ).inject_to(self) filtered_kwargs = kwargs.reject { |key, _| key == :dependencies } if filtered_kwargs.empty? # https://bugs.ruby-lang.org/issues/14415 super(*args, &block) else super(*args, **filtered_kwargs, &block) end end end
- Defined in:
- lib/flows/plugin/dependency_injector.rb,
lib/flows/plugin/dependency_injector/errors.rb,
lib/flows/plugin/dependency_injector/dependency.rb,
lib/flows/plugin/dependency_injector/dependency_list.rb,
lib/flows/plugin/dependency_injector/dependency_definition.rb
Overview
Allows to inject dependencies on the initialization step.
After including this module you inject dependencies by providing :dependencies
key
to your initializer:
x = MyClass.new(dependencies: { my_dep: -> { 'Hi' } })
x.my_dep
# => 'Hi'
Keys are dependency names. Dependency will be injected as a public method with dependency name. Values are dependencies itself.
You can also require some dependencies to be present. If required dependency is missed - MissingDependencyError will be raised.
If an optional dependency has no default - MissingDependencyDefaultError will be raised.
For an optional dependency default value must be provided.
You can provide a type for the dependency.
Type check uses case equality (===
).
So, it works like Ruby's case
.
In case of type mismatch UnexpectedDependencyTypeError will be raised.
dependency :name, type: String # name should be a string
# by the way, you can use lambdas like in Ruby's `case`
dependency :age, type: ->(x) { x.is_a?(Number) && x > 0 && x < 100 }
If you're trying to inject undeclared dependency - UnexpectedDependencyError will be raised.
Inheritance is supported and dependency definitions will be inherited into child classes.
Defined Under Namespace
Modules: DSL, InheritanceCallback Classes: Dependency, DependencyDefinition, DependencyList, Error, MissingDependencyDefaultError, MissingDependencyError, UnexpectedDependencyError, UnexpectedDependencyTypeError
Constant Summary collapse
- NO_TYPE =
Placeholder for empty type. We cannot use
nil
because value can benil
. :__no_type__
- NO_DEFAULT =
Placeholder for empty default. We cannot use
nil
because value can benil
. :__no_default__
- NO_VALUE =
Placeholder for empty value. We cannot use
nil
because value can benil
. :__no_value__
- SingletonVarsSetup =
Flows::Util::InheritableSingletonVars::DupStrategy.make_module( '@dependencies' => {} )
- InitializerWrapper =
Util::PrependToClass.make_module do def initialize(*args, **kwargs, &block) # rubocop:disable Metrics/MethodLength if @__dependencies_injected__ if kwargs.empty? # https://bugs.ruby-lang.org/issues/14415 super(*args, &block) else super(*args, **kwargs, &block) end return end @__dependencies_injected__ = true klass = self.class DependencyList.new( klass: klass, definitions: klass.dependencies, provided_values: kwargs[:dependencies].dup || {} ).inject_to(self) filtered_kwargs = kwargs.reject { |key, _| key == :dependencies } if filtered_kwargs.empty? # https://bugs.ruby-lang.org/issues/14415 super(*args, &block) else super(*args, **filtered_kwargs, &block) end end end