Module: SenroUsecaser::DependsOn

Included in:
Base, Hook
Defined in:
lib/senro_usecaser/depends_on.rb

Overview

Module that provides dependency injection support

This module can be extended into any class to enable the full DI functionality similar to UseCase and Hook classes, including:

  • depends_on for declaring dependencies
  • namespace for scoped dependency resolution
  • Automatic infer_namespace_from_module support
  • Default initialize that sets up dependency injection (uses SenroUsecaser.container if not provided)

Examples:

Basic usage (no initialize needed)

class MyService
  extend SenroUsecaser::DependsOn

  depends_on :logger, Logger
  depends_on :repository

  # No initialize needed! Default is provided automatically.

  def perform
    logger.info("Performing...")
    repository.find(1)
  end
end

service = MyService.new  # Uses SenroUsecaser.container
service.logger  # => Logger instance

Custom initialize with super

class MyService
  extend SenroUsecaser::DependsOn

  depends_on :logger
  attr_reader :extra

  def initialize(extra:, container: nil)
    super(container: container)  # Handles dependency resolution
    @extra = extra
  end
end

With explicit namespace

class Admin::UserService
  extend SenroUsecaser::DependsOn

  namespace :admin
  depends_on :user_repository, UserRepository
end

With infer_namespace_from_module (when configured)

# When SenroUsecaser.configuration.infer_namespace_from_module = true
class Admin::Orders::ProcessService
  extend SenroUsecaser::DependsOn

  depends_on :order_repository  # resolved from "admin::orders" namespace
end

Defined Under Namespace

Modules: InstanceMethods

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.extended(base) ⇒ Object

Hook called when module is extended into a class Automatically includes InstanceMethods



65
66
67
# File 'lib/senro_usecaser/depends_on.rb', line 65

def self.extended(base)
  base.include(InstanceMethods)
end

Instance Method Details

#copy_depends_on_to(subclass) ⇒ Object

Copies dependency configuration to a subclass

: (Class) -> void

Examples:

In inherited hook

def self.inherited(subclass)
  super
  copy_depends_on_to(subclass)
end

Parameters:

  • subclass (Class) —

    The subclass to copy dependencies to



142
143
144
145
146
# File 'lib/senro_usecaser/depends_on.rb', line 142

def copy_depends_on_to(subclass)
  subclass.instance_variable_set(:@dependencies, dependencies.dup)
  subclass.instance_variable_set(:@dependency_types, dependency_types.dup)
  subclass.instance_variable_set(:@declared_namespace, @declared_namespace)
end

#declared_namespace ⇒ Object

Returns the declared namespace

: () -> (Symbol | String)?



127
128
129
# File 'lib/senro_usecaser/depends_on.rb', line 127

def declared_namespace
  @declared_namespace
end

#dependencies ⇒ Object

Returns the list of declared dependencies

: () -> Array



93
94
95
# File 'lib/senro_usecaser/depends_on.rb', line 93

def dependencies
  @dependencies ||= []
end

#dependency_types ⇒ Object

Returns the dependency type mapping

: () -> Hash[Symbol, Class]



100
101
102
# File 'lib/senro_usecaser/depends_on.rb', line 100

def dependency_types
  @dependency_types ||= {}
end

#depends_on(name, type = nil) ⇒ Object

Declares a dependency to be injected from the container

: (Symbol, ?Class) -> void

Examples:

Basic dependency

depends_on :logger

Typed dependency

depends_on :repository, UserRepository

Parameters:

  • name (Symbol) —

    The name of the dependency

  • type (Class, nil) (defaults to: nil) —

    Optional expected type for the dependency



81
82
83
84
85
86
87
88
# File 'lib/senro_usecaser/depends_on.rb', line 81

def depends_on(name, type = nil)
  dependencies << name unless dependencies.include?(name)
  dependency_types[name] = type if type

  define_method(name) do # steep:ignore NoMethod
    @_dependencies[name]
  end
end

#namespace(name = nil) ⇒ Symbol, ...

Sets or returns the namespace for dependency resolution

: (?(Symbol | String)) -> (Symbol | String)?

Examples:

Setting namespace

namespace :admin

Getting namespace

current_ns = namespace

Parameters:

  • name (Symbol, String, nil) (defaults to: nil) —

    The namespace to set

Returns:

  • (Symbol, String, nil) —

    The current namespace when no argument given



116
117
118
119
120
121
122
# File 'lib/senro_usecaser/depends_on.rb', line 116

def namespace(name = nil)
  if name
    @declared_namespace = name
  else
    @declared_namespace
  end
end