Question about dry-system and auto register


#1

Is there a way to manipulate the component key that is generated by auto_registrar?

…given a class that is in a deep directory structure…

# lib/company/project/interactors/users/some_worker.rb
module Company::Project::Interactors::Users
  class SomeWorker
    ...
  end
end

The key becomes quite long and I would like to possibly match for a pattern and replace it. Like for the above, any component identifiers with “company.project.interactors.users.someworker” would be replaced simply with “interactors”. …so for the above it would be “interactors.users.someworker

What would be the best approach here?

I see there is a AutoRegistrar class, would I have to supply my own version of this or is there a better way? Maybe somewhere else, as I see the component should already have its identifier by this point?


#2

We actually have a (relatively recently added) feature to support this very thing!

Try adding this config to your container:

module Company
  module Project
    class Container < Dry::System::Container # or whatever your container is
      configure do |config|
        config.default_namespace = "company.project"
      end
    end
  end
end

This means, that when you auto-register, your Company::Project::Interactors:Users::SomeWorker object will be registered with a key of "interactors.users.some_worker".

Let me know how this goes!


#3

Hey Tim,

It looks like you can’t have the separator appear in the default namespace.

[59, 68] in /home/david/.gem/ruby/2.3.1/gems/dry-system-0.5.1/lib/dry/system/component.rb
   59:       end
   60: 
   61:       # @api private
   62:       def self.ensure_valid_namespace(ns, sep)
   63:         ns_name = ns.to_s
=> 64:         raise InvalidNamespaceError, ns_name if ns && ns_name.include?(sep)
   65:         ns_name
   66:       end
   67: 
   68:       # @api private
(byebug) ns_name
"carbide.domain"
(byebug) sep
"."
(byebug) ns_name.include?(sep)
true
(byebug) 

…so I get an InvalidNamespaceError.


#4

…I tried using a path separator in the name_space to follow it through. Looks like it can only work with a single name, as the components path gets separated into an array and then the array rejects anything matching the namespace.

[71, 80] in /home/david/.gem/ruby/2.3.1/gems/dry-system-0.5.1/lib/dry/system/component.rb
   71: 
   72:         if keys.uniq.size != keys.size
   73:           raise InvalidComponentError, name, 'duplicated keys in the name'
   74:         end
   75: 
=> 76:         keys.reject { |s| ns_name == s }.join(sep)
   77:       end
   78: 
   79:       # @api private
   80:       def self.cache
(byebug) keys
["persistence", "repositories", "campaigns"]
(byebug) ns_name
"carbide/domain"
(byebug) 

#5

Thanks for your report, @dvallance! I guess we’ve only used single namespaces with this feature so far. I think it should be updated to work with a nested namespace – would you mind filing an issue on dry-system about this?


#6

Issue submitted. …thanks Tim.


#7

@dvallance These issue has been fixed. :slight_smile:


#8

Awesome! Thank you very much…