module LunaPark::Extensions::Injector
The main goal of the injector is a help developer with dependency injection technique.
@example 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
@example 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
Public Class Methods
included(base)
click to toggle source
@!parse include Injector::ClassMethods
@!parse extend Injector::InstanceMethods
# File lib/luna_park/extensions/injector.rb, line 105 def self.included(base) base.extend ClassMethods base.include InstanceMethods end