Module: LunaPark::Extensions::Injector

Extended by:
InstanceMethods
Includes:
ClassMethods
Included in:
Notifiers::Sentry
Defined in:
lib/luna_park/extensions/injector.rb,
lib/luna_park/extensions/injector/dependencies.rb

Overview

The main goal of the injector is a help developer with dependency injection technique.

Examples:

Dependency injection

class Messenger
  def self.post(to:, msg:); end
end

module Users
  class Entity
    def active!; end
    def full_name;end
  end

  class PgRepo
    def find(id); end
    def save(user); end
  end

  # In this example, you can see the relationship between
  # the business layer and the data layer, and between the
  # business layer and external libraries.

  class SetActive < LunaPark::UseCases::Scenario
    include LunaPark::Extensions::Injector

    attr_accessor :user_id

    def call!
      repo = Users::PgRepo.new # <- dependency from data layer
      user = repo.find(user_id)
      user.active!
      repo.save user

      Messenger.post(to: :admin, msg:"User #{user.full_name} is active_now") # <- dependency from external libs
    end
  end
end

# Here, Injector can help remove the dependency technical details from
# the business layer.

class SetActive < LunaPark::Interactors::Scenario
  include LunaPark::Extensions::Injector

  dependency(:repo)      { Users::PgRepo.new } # You should define dependency in block - like rspec `let`
                                               # method. That should initialize value only if that needed.
  dependency(:messenger) { Messenger }

  attr_accessor :user_id

  def call!
    user = repo.find(user_id)
    user.active!
    repo.save user

    messenger.post(to: :admin, msg:"User #{user.full_name} is active_now")
  end
end

rspec test

module Users
  RSpec.describe SetActive do
    # We highly dont recommended inject dependencies witch does not call exteranal resources
    let(:user)       { Entity.new id: 1, first_name: 'John', last_name: 'Doe'}
    let(:use_case) { described_class.new(user_id: 1) }

    before do
      use_case.dependencies = {
        repo: -> { instance_double PgRepo, find: user, save: true },
        messenger: -> { class_double Messenger, post: true }
      }
    end

    describe '#call!' do
      subject(:set_active!) { use_case.call! }

      it 'should set user is active' do
        expect{ set_active! }.to change{ user.active? }.from(false).to(true)
      end

      it 'should save user' do
        expect(use_case.repo).to receive(:save).with(user)
        set_active!
      end

      it 'should send expected message to admin' do
        text = 'User John Doe is active_now'
        expect(use_case.messenger).to receive(:post).with(to: :admin, msg: text)
        set_active!
      end
    end
  end
end

Defined Under Namespace

Modules: ClassMethods, InstanceMethods Classes: Dependencies

Class Method Summary collapse

Methods included from InstanceMethods

dependencies, dependencies=, inject

Methods included from ClassMethods

#dependencies, #dependency, #inherited

Class Method Details

.included(base) ⇒ Object



105
106
107
108
# File 'lib/luna_park/extensions/injector.rb', line 105

def self.included(base)
  base.extend ClassMethods
  base.include InstanceMethods
end