You need only one thing before you can use dry-auto_inject: a container to hold your application’s dependencies. These are commonly known as “inversion of control” containers.
A dry-container will work well, but the only requirement is that the container responds to the
# interface. For example,
my_container["users_repository"] should return the “users_repository” object registered with the container.
Creating an injector
To create an injector, pass the container to
Import = Dry::AutoInject(my_container)
Assign the injector to a constant (or make it globally accessible somehow) so you can refer to it from within your classes.
To specify the dependencies for a class, mix in the injector and provide the container identifiers for each dependency:
class MyClass include Import["users_repository", "deliver_welcome_email"] end
Each dependency is available via a reader with a matching name:
class MyClass include Import["users_repository"] def call puts users_repository.inspect end end
If your container identifiers include delimiters (like
".") or other characters that are not allowed within variable or method names, then the final part of the name will be used instead:
class MyClass include Import["repositories.users"] def call puts users.inspect end end
Specifying aliases for dependencies
You can specify dependencies as a hash to provide your own names for each one:
class MyClass include Import[users_repo: "repositories.users"] def call puts users_repo.inspect end end
If you want to provide a mix of inferred names and aliases, provide the aliases last:
class MyClass include Import[ "repositories.users", deliver_email: "operations.deliver_welcome_email", ] end
Initializing your object
Initialize your object without any arguments and all the dependencies will be resolved from the the container automatically:
my_obj = MyClass.new
Passing manual dependencies
To provide an alternative object for a dependency, pass it to the initializer with a keyword argument matching the dependency’s name:
class MyClass include Import["repositories.users"] end my_obj = MyClass.new(users: different_repo)
This technique is useful when testing your class in isolation. You can pass in test doubles to verify your class’ behaviour under various different circumstances.