Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Object dependency injection #117

Open
Hugo-Hache opened this issue Jan 16, 2019 · 0 comments
Open

Object dependency injection #117

Hugo-Hache opened this issue Jan 16, 2019 · 0 comments

Comments

@Hugo-Hache
Copy link

Hugo-Hache commented Jan 16, 2019

Existing injection mechanism allows today to inject operations. I'd like to know what you think about injecting instances.

I know dry-transaction brings a lot of greatness from the functional programming world, where object-oriented obsession with classes is replaced with functions.

However in a project with an architecture enforcing clear responsibilities to objects, dependency injection would be much simpler with instances rather than operation.

Here is a use case with repository injection.

class CongratulateUser
  include Dry::Transaction

  step :retrieve
  step :congratulate

  private

  def retrieve(user_id:)
    user = UserRepository.new.retrieve(user_id)
    user ? Success(user) : Failure(:not_found)
  end

  def congratulate(user)
    puts "Kudos #{user.email}!"
    Success(user)
  end
end

Today we would do need to inject the full retrieve operation, reimplementing Success and Failure creation.

retrieve = lambda do |user_id|
  user = UserDatabaseRepository.new.retrieve(user_id)
  user ? Success(user) : Failure(:not_found)
end
CongratulateUser.new(retrieve: retrieve).call(user_id: 42)

Injecting an instance would be much simpler:

class CongratulateUser
  ...
  def retrieve(user_id:)
    user = repository.retrieve(user_id)
    user ? Success(user) : Failure(:not_found)
  end
  ...
end

CongratulateUser.new(repository: UserDatabaseRepository.new).call(user_id: 42)

I thought about passing the instance in the input, but it doesn't make sense for me to consider it as a parameter of my business operation, and moreover it would mean passing it along several steps if not used in the first.

I know that my simplistic API as arg of the initialize hash is not compatible with current operations mechanism. I'd simply like to know what you think about instances injection, and if you see a cleaner functional way to do it, which one?

Thanks a lot for your work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant