Home

Practical example of dependency injection in Ruby

20 Jan 2014 / hacking

Today while working on my next great and amaizing project I used programming pattern called dependency injection.

Dependency injection is software design pattern that allows the removal of hard-coded dependencies and makes it possible to change them in "run-time" or "compile time".

We have a class/model called Flow that after person is added to Flow sends email to person who was added. Since Flow needs FlowMailer to send emails that means that there is dependency between Flow and FlowMailer.

This is how the code looks without pettern.

class Flow

  def add_access! user
    access = accesses.create!(user)
    FlowMailer.access_created access
  end

end

And this is how the class looks with dependency injection pattern.

class Flow

  attr_writer :mailer
  def mailer
    @mailer ||= FlowMailer
  end

  def add_access! user
    access = accesses.create!(user)
    mailer.access_created access
  end

end

Why is this better?

Because now among other things you can test your code decupled and you can swap mailer anytime you want with whatever you want. Like with double for example.

describe Flow do
  let!(:flow){ create :flow }
  let(:user){ flow.creator }
  let(:other_user){ create :user }

  context "#add_access!" do
    # Create double
    let(:mailer) { double("FlowMailer") }

    # "Inject" double into object
    before { flow.mailer = mailer }

    it do
      expect(mailer).to receive(:access_created).once

      expect { flow.add_access!(other_user) }
      .to change(flow.flow_accesses, :count).from(1).to(2)
    end

end

To find more about dependency injection I suggest that you also look int this resources:


comments powered by Disqus