• One of the things that I find more interesting from Hanakai is their approach to dependency injection. dry-container+dry-autoject is the first dependency injection framework that looked aligned with Ruby values ‘values’.

    Most of the time one doesn’t need to do dependency injection in Ruby, and keyword arguments + memoization can be used in most of the cases where I would want to reach for DI. This post explains the perspective dry-container and friends are coming from.

    How they divide arguments to the class vs to the method is a little different to how I normally write Ruby but it is a divide that I can make sense of. In the spectrum of what is a dependency there are several answers. From the infra perspective it might be a 3rd party service (Postgres, Redis, MailChimp, etc). A maximalist view in the language perspective might be that collaborator classes are a dependency [in the global namespace] and that is the perspective where the proposed divide is coming from.

    The way I would regularly write the class would be to inline some dependencies like UserRepository, which I normally don’t try to substitute during tests. And things like Confirmation mailer would be a memoized method which we can override with a keyword argument during tests.

    class UserRegistration
      def initialize(email, password, confirmation:); ...; end
      def confirmation; @comfirmation ||= ConfirmationMailer.new
    

    The resulting service class might look a little unusual at first, but the design is more testable without resorting to things like method stubs.


    score 1 · canonical