Simple Dependency Injection in Ruby
Basically Dependency Injection is a practice used to remove dependencies or tight coupling between different objects.
To learn more about DI, I recommend you read this article by Martin Fowler and also this topic.
I usually use DI through Constructor Injection, this approach allows you to inject the dependencies passing to the object on the constructor method. But isn’t always necessary to inject the dependencies when to instantiate the class, you can avoid it by using Hash.fetch to declare the default dependencies.
For example, imagine that we have a repository class as a dependency:
class Repository
def initialize; end def save
'repository class'
end
end
So here’s an example how I use DI to inject this repository:
class CreateService
def initialize(klasses = {})
@repository = klasses.fetch(:repository) { Repository.new }
end def call
repository.save
end private
attr_reader :repository
end
Hash.fetch
makes it simple to instantiate the service with default dependencies:
p CreateService.new.call
# "repository class"
and it also makes simple the dependency replacement, see an example with another repository:
class OtherRepository
def initialize; end def save
'other_repository class'
end
endp CreateService.new({ repository: OtherRepository.new }).call
# "other_repository class"
One last detail is to use the attributes as private, to prevent dependencies from being exposed:
private
attr_reader :repository