dry-rb / dry-container

A simple, configurable object container implemented in Ruby
https://dry-rb.org/gems/dry-container
MIT License
335 stars 41 forks source link

Allow overwriting of component keys in container #37

Closed illogikal closed 7 years ago

illogikal commented 7 years ago

I have a dry system container that has dependencies organized by namespace. I also want to create keys for arrays of component types i can operate on with an enum. What would be the best way of doing this? Each dependency has a method like below so I can call the method in an aggregate way.

class Foo::Bar
def self.register!
        Container.register('foo.bar', Foo::Bar)
        bars = (Container['foo.bars'] rescue []) << Foo::Bar
        Container.register('foo.bars', bars)
end
end

class Foo::Bar2
def self.register!
        Container.register('foo.bar2', Foo::Bar2)
        bars = (Container['foo.bars'] rescue []) << Foo::Bar2
        Container.register('foo.bars', bars)
end
end

..

Foo::Bar.register!
Foo::Bar2.register!
Container.finalize!

OPTION 1 Container['foo.bars'] #should equal [Foo::Bar, Foo::Bar2]
OPTION 2 Container['foo'] #should equal [Foo::Bar, Foo::Bar2]

What would be a good way of achieving this in a dry fashion? Is this currently possible?

AMHOL commented 7 years ago

I'm not sure I completely understand what you're trying to do, but it looks like something like this would work:

gemfile(true) { gem 'dry-container' }

# This won't be necessary in your example
Container = Dry::Container.new

# Before calling the `register!` methods, register a default value
# for 'foo.bars' with the `memoize` option set to false
Container.register('foo.bars', [], memoize: false)

module Foo
  class Bar
    def self.register!
      Container.register('foo.bar', Foo::Bar)
      Container['foo.bars'] << Foo::Bar
    end
  end

  class Bar2
    def self.register!
      Container.register('foo.bar2', Foo::Bar2)
      Container['foo.bars'] << Foo::Bar2
    end
  end
end

Foo::Bar.register!
Foo::Bar2.register!
# Commented out as not using dry-system
# Container.finalize!

Container['foo.bars']
# => [Foo::Bar, Foo::Bar2]
illogikal commented 7 years ago

Ah that totally makes sense. I for some reason assumed references were immutable. Thanks!

AMHOL commented 7 years ago

NP :smile: