Sha256: 5a557fcdb4c9065cc9e718be25cff4fe691bce64e07aae3f78536c3c89b2657c

Contents?: true

Size: 1.7 KB

Versions: 1

Compression:

Stored size: 1.7 KB

Contents

module Koine
  module Di
    # The dependency container class
    class DependencyContainer
      class UndefinedDependency < RuntimeError; end
      class DependencyAlreadyDefined < RuntimeError; end

      def initialize
        @factories = {}
        @shared_factories = {}
        @instances = {}
      end

      def share(dependency, &block)
        ensure_undefined(dependency)
        shared_factories[to_key(dependency)] = block
        self
      end

      def set(dependency, &block)
        ensure_undefined(dependency)
        factories[to_key(dependency)] = block
        self
      end

      def defined?(dependency)
        key = to_key(dependency)
        shared_factories.key?(key) || factories.key?(key)
      end

      def get(dependency, &_block)
        key = to_key(dependency)

        if self.defined?(key)
          return from_shared_factories(key) || from_factories(key)
        end

        return yield if block_given?

        fail UndefinedDependency, "'#{dependency}' was not defined"
      end

      def add_factory(factory)
        factory.attach_to(self)
      end

      protected

      attr_reader :factories
      attr_reader :instances
      attr_reader :shared_factories

      def from_shared_factories(key)
        return unless shared_factories.key?(key)
        instances[key] ||= shared_factories[key].call(self)
      end

      def from_factories(key)
        factories[key].call(self) if factories.key?(key)
      end

      def ensure_undefined(dependency)
        return unless self.defined?(dependency)
        fail DependencyAlreadyDefined,
          "Dependency '#{dependency}' was already defined"
      end

      def to_key(object)
        object.to_s
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
koine-di-1.0.0 lib/koine/di/dependency_container.rb