Using dry-struct with dry-system

I’m a bit confused about how dry-struct fits into dry-system.

The auto injector assumes that any dependency I import should get .new called on it before providing it as a method on the current object, but this doesn’t behave well with importing a dry-struct. I understand I can manually register a struct, so I can then pass .new myself with the required arguments, but is this even something I should be doing with dry-system? Perhaps I shouldn’t think of my structs as the types of “dependencies” that dry-system wants me to import, but I thought I’d ask here for some clarification.

Here’s a brief (and overly-simplified) example of what I’m talking about:

# system/container.rb
#...
require "structs/note"
Application.register "note", Structs::Note

# lib/cli/commands/create_note.rb
class CreateNote
  include Import['note']

  def call(params)
    note.new params
  end
end

I could avoid the above by doing something like the following, but I’m not sure if it’s overkill:

# lib/interactors/note_creator.rb
require "structs/note"
class NoteCreator
  include Dry::Monads[:result]
  include Dry::Monads::Do.for(:call)

  def call(params)
    Success(Structs::Note.new(params))
  end
end

# lib/cli/commands/create_note.rb
class CreateNote
  include Import['interactors.note_creator']

  def call(params)
    note_creator.call params
  end
end

Am I misunderstanding the purpose of dry-system and over-using it a bit? Any guidance anyone could provide would be very appreciated :heart:

Structs represent pure data structures and should not be treated as objects that you inject as dependencies. They don’t “do things”, they only expose values. There’s simply no reason for injecting them anywhere because of this.

Okay, that’s a helpful rule of thumb. And I suppose the direct requires of the structs might end up hidden behind a repository which I may or may not require as a dependency.

Thanks for the insight :+1:

exactly, that’s what I do actually, repositories require structs that they return.

1 Like