Adding dry-rails to monolith Rails app works like a charm, thanks for all the work 🙇♂️
However, it's not so great when used with Engines :bowtie:
There's no way for an Engine to define its own Container
There's no way to not have Container for main app (sounds odd but that's actually our use case, we want to have DRY-rb setup only in one Engine)
I think each Engine should define its own Container, otherwise we're loosing whole namespace isolation that Engines provide
MainApp::Container.resolve('users.create') #> Dry::Container::Error: Nothing registered with the key "users.create"
SuperComponent::Container.resolve('users.create') #> #<SomeComponent::Users::Create:0x00007fa6d963e368>
🥳
# /components/some_component/lib/some_component/engine.rb
module SuperComponent
class Engine < ::Rails::Engine
isolate_namespace SuperComponent
initializer 'super_component.dry_container' do |_app|
Dry::Rails::Engine.container(:super_component) do
config.features = %i[application_contract]
config.auto_registrar = Dry::System::AutoRegistrar
auto_register!('domain')
end
end
config.to_prepare do
Engine.finalize!
end
# Code-reloading-aware finalization process
#
# This sets up `Container` and `Deps` constants, reloads them if this is in reloading mode,
# and registers default components like the railtie itself or the inflector
#
# @api public
#
delegate :finalize!, to: :finalizer
alias reload finalize!
# Stops all configured features (bootable components)
#
# This is *crucial* when reloading code in development mode. Every bootable component
# should be able to clear the runtime from any constants that it created in its `stop`
# lifecycle step
#
# @api public
delegate :stop_features, to: :finalizer
# Exposes the container constant
#
# @return [Dry::Rails::Container]
#
# @api public
delegate :container, to: :finalizer
# @api private
delegate :set_or_reload, to: :finalizer
# @api private
delegate :remove_constant, to: :finalizer
private
def finalizer
@finalizer ||= Dry::Rails::Engine::Finalizer.new(
railtie: self,
app_namespace: SuperComponent,
root_path: ::Rails.root.join('components/super_component'),
)
end
end
end
# /components/some_component/domain/some_component/users/create.rb
module SuperComponent
module Users
class Create
end
end
end
Closed in favour of #49
Don't mind me yet, just looking what's what 👀
Adding dry-rails to monolith Rails app works like a charm, thanks for all the work 🙇♂️
However, it's not so great when used with Engines :bowtie:
I think each Engine should define its own Container, otherwise we're loosing whole namespace isolation that Engines provide
🥳