Using dry-auto_inject with Active Job

Hi all,

I am using dry gems with Rails 5 (I know that it’s not recommended but currently I have no choice).

I inject dependency from DI container into Active Job task - it all works great as long as I create and run task manually:

MyTask.new.perform args

But if I try to schedule the task using perform_later I get this error:

ArgumentError: wrong number of arguments (given 1, expected 0)
from /Users/tap/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/dry-auto_inject-0.4.1/lib/dry/auto_inject/strategies/kwargs.rb:12:in `new'

The point is that when using perform_later Rails creates new object with new(*args) passing arguments for perform method inside contstructor (https://github.com/rails/rails/blob/master/activejob/lib/active_job/configured_job.rb#L13). But dry-auto_inject redefines new method and expects keywords arguments instead of positional ones and this is why error occurs.

Is there any way to avoid this error and make Active Job work with dry-auto_inject?

Thanks in advance.

At first glance, I’d say that looks like the design of the ActiveJob class is incompatible with what dry-auto_inject requires (control over object initialization).

I think your best bet might be to write a custom dry-auto_inject injection strategy that doesn’t use the initializer. dry-auto_inject lets you pass in a container of strategies like so:

MyInject = Dry::AutoInject(MyContainer, strategies: MyStrategies)

You can see the standard strategies here: https://github.com/dry-rb/dry-auto_inject/blob/master/lib/dry/auto_inject/strategies.rb (they’re all required below the default strategies container).

We don’t have detailed documentation about building your own strategy right now, but hopefully the existing implementations should help guide you!

1 Like