Harry
Harry

Reputation: 1699

Ruby/Rails Dependency Injection

I am trying to learn about dependency injection in Ruby/Rails. How can I remove Builders explicit reference to Saw using dependency injection?

class Builder
  attr_reader :saw

  def saw
    @saw ||= Saw.new(4)
  end

  def cut_wood
    Saw.saw
  end
end

class Saw
  attr_reader :blades

  def initialize(blades)
    @blades = blades
  end

  def saw
    # do something
  end
end

Upvotes: 4

Views: 1325

Answers (2)

shime
shime

Reputation: 9008

Move initialization of Saw to the default argument.

class Builder   
  def saw(saw = Saw.new(4))
    @saw = saw
  end

  def cut_wood
    Saw.saw
  end
end

Builder#saw supports dependency injection now.

Remember to remove attr_reader :saw from your code because it's being overridden by your custom reader.

Upvotes: 4

Billy Chan
Billy Chan

Reputation: 24815

class Builder

  def initialize(saw=Saw.new(4))
    @saw = saw
  end

  def cut_wood
    @saw.saw
  end
end

# Use it
b = Builder.new
b.saw

another_saw = AnotherSaw.new
b = Builder.new(another_saw)
b.saw

You initialize the Builder instance by a default saw. So you can either use the default one or use your own. This way you decoupled Saw from Builder.

By the way, I don't know hammer is for so I didn't write it. It looks nothing more than an attr reader in your code.

Also I don't need the necessity of attr_read :saw so I removed it.

Upvotes: 3

Related Questions