- New hook -
before(:configure)which a plugin should use if it needs to declare new settings (@solnic)
# in your plugin code
before(:configure) { setting :my_new_setting }
after(:configure) { config.my_new_setting = "awesome" }- Centralize error definitions in
lib/dry/system/errors.rb(@cgeorgii) - All built-in plugins use
before(:configure)now to declare their settings (@solnic)
- Use
Kernel.requireexplicitly to avoid issues with monkey-patchedrequirefrom ActiveSupport (@solnic)
- Misspelled plugin name raises meaningful error (issue #132) (@cgeorgii)
- Fail fast if auto_registrar config contains incorrect path (@cutalion)
- More keyword warnings (flash-gordon)
- Fixed keyword warnings reported by Ruby 2.7 (flash-gordon)
- Duplicates in
Dry::System::Plugins.loaded_dependencies(AMHOL)
Container.resolveaccepts and optional block parameter which will be called if component cannot be found. This makes dry-system consistent with dry-container 0.7.2 (flash-gordon)App.resolve('missing.dep') { :fallback } # => :fallback
- [BREAKING]
Container.key?triggers lazy-loading for not finalized containers. If component wasn't found it returnsfalsewithout raising an error. This is a breaking change, if you seek the previous behavior, useContainer.registered?(flash-gordon)
- Compatibility with dry-struct 1.0 and dry-types 1.0 (flash-gordon)
- [BREAKING]
:decorateplugin was moved from dry-system to dry-container (available in 0.7.0+). To upgrade removeuse :decorateand changedecoratecalls fromdecorate(key, decorator: something)todecorate(key, with: something)(flash-gordon) - [internal] Compatibility with dry-struct 0.7.0 and dry-types 0.15.0
- Support for stopping bootable components with
Container.stop(component_name)(GustavoCaso)
- When using a non-finalized container, you can now resolve multiple different container objects registered using the same root key as a bootable component (timriley)
-
You can now set a custom inflector on the container level. As a result, the
Loader's constructor accepts two arguments:pathandinflector, update your custom loaders accordingly (flash-gordon)class MyContainer < Dry::System::Container configure do |config| config.inflector = Dry::Inflector.new do |inflections| inflections.acronym('API') end end end
- A helpful error will be raised if an invalid setting value is provided (GustavoCaso)
- When using setting plugin, will use default values from types (GustavoCaso)
- Minimal supported ruby version was bumped to
2.3(flash-gordon) dry-structwas updated to~> 0.5(flash-gordon)
- Default namespace no longer breaks resolving dependencies with identifier that includes part of the namespace (ie
mail.mailer) (GustavoCaso)
- Plugin dependencies are now auto-required and a meaningful error is raised when a dep failed to load (solnic)
- Plugin API (solnic)
:envplugin which adds support for settingenvconfig value (solnic):loggingplugin which adds a default logger (solnic):decorateplugin for decorating registered objects (solnic):notificationsplugin adding pub/sub bus to containers (solnic):monitoringplugin which addsmonitormethod for monitoring object method calls (solnic):bootsnapplugin which adds support for bootsnap (solnic)
- [BREAKING] renamed
Container.{require=>require_from_root}(GustavoCaso)
- Aliasing an external component works correctly (solnic)
- Manually calling
:initwill also finalize a component (solnic)
- Support for external bootable components (solnic)
- Built-in
:systemcomponents including:settingscomponent (solnic)
- Lazy-loading components work when a container has
default_namespaceconfigured (GustavoCaso)
- [BREAKING] Improved boot DSL with support for namespacing and lifecycle before/after callbacks (solnic)
Container.enable_stubs!calls super too, which actually addsstubAPI (solnic)- Issues with lazy-loading and import in stub mode are gone (solnic)
Container.enable_stubs!for test environments which enables stubbing components (GustavoCaso)
- Component identifiers can now include same name more than once ie
foo.stuff.foo(GustavoCaso) Container#boot!was renamed toContainer#start(davydovanton)Container#bootwas renamed toContainer#init(davydovanton)
- Accept string values for Container's
rootconfig (timriley)
-
Added
manual_registrarcontainer setting (along with defaultManualRegistrarimplementation), andregistrations_dirsetting. These provide support for a well-established place for keeping files with manual container registrations (timriley) -
AutoRegistrar parses initial lines of Ruby source files for "magic comments" when auto-registering components. An
# auto_register: falsemagic comment will prevent a Ruby file from being auto-registered (timriley) -
Container.auto_register!, when called with a block, yields a configuration object to control the auto-registration behavior for that path, with support for configuring 2 different aspects of auto-registration behavior (both optional):class MyContainer < Dry::System::Container auto_register!('lib') do |config| config.instance do |component| # custom logic for initializing a component end config.exclude do |component| # return true to skip auto-registration of the component, e.g. # component.path =~ /entities/ end end end
-
A helpful error will be raised if a bootable component's finalize block name doesn't match its boot file name (GustavoCaso)
- The
default_namespacecontainer setting now supports multi-level namespaces (GustavoCaso) Container.auto_register!yields a configuration block instead of a block for returning a custom instance (see above) (GustavoCaso)Container.importnow requires an explicit local name for the imported container (e.g.import(local_name: AnotherContainer)) (timriley)
- Lazy load components as they are resolved, rather than on injection (timriley)
- Perform registration even though component already required (blelump)
- Undefined locals or method calls will raise proper exceptions in Lifecycle DSL (aradunovic)
for multi-container setups. As part of this release dry-system has been renamed to dry-system.
- Boot DSL with:
- Lifecycle triggers:
init,startandstop(solnic) usemethod which auto-boots a dependency and makes it available in the booting context (solnic)
- Lifecycle triggers:
- When a component relies on a bootable component, and is being loaded in isolation, the component will be booted automatically (solnic)
- [BREAKING]
Dry::Component::Containeris nowDry::System::Container(solnic) - [BREAKING] Configurable
loaderis now a class that accepts container's config and responds to#constantand#instance(solnic) - [BREAKING]
core_dirrenameda tosystem_dirand defaults tosystem(solnic) - [BREAKING]
auto_register!yieldsComponentobjects (solnic)
- Return immediately from
Container.load_componentif the requested component key already exists in the container. This fixes a crash when requesting to load a manually registered component with a name that doesn't map to a filename (timriley in #24)
- Ensure file components can be loaded when they're requested for the first time using their shorthand container identifier (i.e. with the container's default namespace removed) (timriley)
- Require the 0.4.0 release of dry-auto_inject for the features below (in 0.4.0) to work properly (timriley)
-
Support for supplying a default namespace to a container, which is passed to the container's injector to allow for convenient shorthand access to registered objects in the same namespace (timriley in #20)
# Set up container with default namespace module Admin class Container < Dry::Component::Container configure do |config| config.root = Pathname.new(__dir__).join("../..") config.default_namespace = "admin" end end Import = Container.injector end module Admin class CreateUser # "users.repository" will resolve an Admin::Users::Repository instance, # where previously you had to identify it as "admin.users.repository" include Admin::Import["users.repository"] end end
-
Support for supplying to options directly to dry-auto_inject's
BuilderviaDry::Component::Container#injector(options). This allows you to provide dry-auto_inject customizations like your own container of injection strategies (timriley in #20) -
Support for accessing all available injector strategies, not just the defaults (e.g.
MyContainer.injector.some_custom_strategy) (timriley in #19)
- Subclasses of
Dry::Component::Containerno longer have anInjectorconstant automatically defined within them. The recommended approach is to save your own injector object to a constant, which allows you to pass options to it at the same time, e.g.MyApp::Import = MyApp::Container.injector(my_options)(timriley in #19)
Removed two pieces that are moving to dry-web:
- Removed two pieces that are moving to dry-web:
- Removed
envsetting fromContainer(timriley) - Removed
Dry::Component::Configandoptionssetting fromContainer(timriley) - Changed
Component#configurebehavior so it can be run multiple times for configuration to be applied in multiple passes (timriley)
- Fixed bug where specified auto-inject strategies were not respected (timriley)
- Component core directory is now
component/by default (timriley) - Injector default stragegy is now whatever dry-auto_inject's default is (rather than hard-coding a particular default strategy for dry-system) (timriley)
-
Provide a dependency injector as an
Injectconstant inside any subclass ofDry::Component::Container. This injector supports all ofdry-auto_inject's default injection strategies, and will lazily load any dependencies as they are injected. It also supports arbitrarily switching strategies, so they can be used in different classes as required (e.g.include MyComponent::Inject.args["dep"]) (timriley) -
Support aliased dependency names when calling the injector object (e.g.
MyComponent::Inject[foo: "my_app.foo", bar: "another.thing"]) (timriley) -
Allow a custom dependency loader to be set on a container via its config (AMHOL)
class MyContainer < Dry::Component::Container configure do |config| # other config config.loader = MyLoader end end
Container.bootnow only makes a simplerequirefor the boot file (solnic)- Container object is passed to
Container.finalizeblocks (solnic) - Allow
Pathnameobjects passed toContainer.require(solnic) - Support lazily loading missing dependencies from imported containers (solnic)
Container.import_modulerenamed to.injector(timriley)- Default injection strategy is now
kwargs, courtesy of the new dry-auto_inject default (timriley)
- Containers have a
namesetting (solnic) - Containers can be imported into one another (solnic)
- Container name is used to determine the name of its config file (solnic)
First public release, extracted from rodakase project